Adrian R.L.M
All projects

For delivery drivers who want to save time and fuel.

RutaFácil

PWA for delivery couriers: capture locations from WhatsApp and generate the shortest delivery route right on the device.

Timeline2 Weeks
RoleFrontend & PWA Developer
Tech StackReact 18 · Vite · TypeScript
rutafacil-ten.vercel.app
01 of 06

The Problem

Independent delivery couriers receive dozens of orders daily via WhatsApp or messaging apps. Manually planning the sequence of stops leads to significant fuel and time waste, while commercial routing tools require expensive subscriptions or heavy APIs.

  • Wasted fuel and delivery time from estimating stop sequences manually.
  • High friction when copying and pasting addresses between chat apps and navigation tools.
  • Expensive routing subscriptions and API fees that are unviable for independent couriers and local stores.
  • Fragile internet connectivity on the road requiring offline-first capabilities.

The Solution

I designed and engineered RutaFácil, an ultra-fast mobile-first PWA with $0 infrastructure cost. It empowers delivery riders to share addresses directly from WhatsApp to their system Share menu, optimizing delivery sequences locally via heuristic algorithms.

  1. 01

    On-Device TSP Optimization

    Nearest Neighbor heuristic combined with 2-opt local search running in milliseconds on-device, minimizing travel distance without server dependencies.

  2. 02

    Web Share Target Integration

    Leverages the Web Share Target API to receive location links directly from WhatsApp, Google Maps, or Waze in two taps.

  3. 03

    Offline-First PWA

    Installable as a standalone app on mobile devices with local state persistence via Zustand, working reliably in low-connectivity areas.

  4. 04

    Zero-Cost Vector Maps

    Powered by MapLibre GL and Esri World Street Map tiles, delivering smooth vector mapping without recurring commercial API keys.

  5. 05

    Turn-by-Turn Delivery Workflow

    Stop-by-stop guidance with instant Google Maps/Waze launching and one-tap delivery completion.

  6. 06

    Cash Collection & Dispatch Tools

    Track cash-on-delivery payments per stop, generate WhatsApp dispatch notifications, and export route traces to GPX.

Tech Stack

Built with 8 modern technologies, chosen to be fast, secure and easy to maintain.

React 18ViteTypeScriptPWAZustandMapLibre GL
See the full technical breakdown

Frontend

React 18

Build Tool

Vite 6

Language

TypeScript

Mobile & Offline

PWA

Mapping / GIS

MapLibre GL

State Management

Zustand

Animations

Framer Motion

Testing

Vitest

Technical Challenges

Zero-Cost On-Device TSP Optimization

Solving the Traveling Salesperson Problem (TSP) without paying for Google Directions or cloud matrix APIs required implementing a client-side solution combining a Nearest Neighbor greedy baseline with 2-opt segment reversals on Haversine distances. It computes near-optimal routes for up to 30 stops in under 5ms right on the courier's phone.

tsp.tstypescript
// Heurística de Vecino Más Cercano + Mejora 2-Opt (Cálculo On-Device $0)
export function optimizeOrder(
  origin: LatLng,
  stops: LatLng[],
  fixedEnd?: LatLng,
): number[] {
  const n = stops.length;
  if (n <= 1) return stops.map((_, i) => i);

  const points = fixedEnd ? [origin, ...stops, fixedEnd] : [origin, ...stops];
  const dist: number[][] = points.map((a) =>
    points.map((b) => haversineKm(a, b)),
  );
  const endIdx = fixedEnd ? n + 1 : null;

  // 1. Vecino más cercano desde el origen
  const visited = new Array<boolean>(n + 1).fill(false);
  visited[0] = true;
  const path: number[] = [0];
  let current = 0;
  for (let step = 0; step < n; step++) {
    let best = -1;
    let bestDist = Infinity;
    for (let j = 1; j <= n; j++) {
      if (!visited[j] && dist[current][j] < bestDist) {
        bestDist = dist[current][j];
        best = j;
      }
    }
    visited[best] = true;
    path.push(best);
    current = best;
  }
  if (endIdx !== null) path.push(endIdx);

  // 2. Optimización 2-opt: invierte segmentos mientras acorte el camino
  let improved = true;
  while (improved) {
    improved = false;
    for (let i = 1; i < n; i++) {
      for (let k = i + 1; k <= n; k++) {
        const a = path[i - 1];
        const b = path[i];
        const c = path[k];
        const d = k + 1 <= n ? path[k + 1] : endIdx;
        const before = dist[a][b] + (d !== null ? dist[c][d] : 0);
        const after = dist[a][c] + (d !== null ? dist[b][d] : 0);
        if (after < before - 1e-9) {
          let lo = i;
          let hi = k;
          while (lo < hi) {
            [path[lo], path[hi]] = [path[hi], path[lo]];
            lo++;
            hi--;
          }
          improved = true;
        }
      }
    }
  }

  return path.slice(1, n + 1).map((p) => p - 1);
}

Multi-Format Location Parsing & Share Target

Couriers receive locations in wildly varied formats: shortened Google Maps URLs, raw coordinate pairs, Waze links, or copied chat transcripts. Built a resilient regex parser capable of scanning full multi-line conversations and extracting every stop in one pass.

Have a similar problem?

Tell me how you handle it today and I will tell you what can be automated or improved.

Tell me what's holding you back