Overview
JavaScript client for the JustRouting API — routing, distance matrices, map matching, trips, nearest-road lookup, vehicle routing optimization, and geocoding across Southeast Asia. TypeScript-first, compiled to pure ESM with type declarations. No dependencies outside the Node.js standard library (fetch). Requires Node 20.3+.
Install
Quickstart
The coordinates above are in Singapore. See Coordinates must share a country.
Services
AClient exposes eight services.
Routes
routes.get returns the best route. routes.getAll additionally returns alternatives and the snapped input waypoints.
route.geometry holds whichever encoding you asked for:
Matrix
Travel time and distance between many points at once.null for unreachable pairs. The API reports those as null, which is deliberately kept distinct from a genuine zero — that is why durations and distances hold number | null entries.
Map Matching
Snap a noisy GPS trace onto the road network and get the route that was driven.Match extends Route, so every route field (distance, duration, geometry, legs, …) is available, plus the engine’s confidence (0–1). mapMatching.getAll additionally returns tracepoints — the input coordinates snapped to the road network, aligned with your input; an entry is null when the engine could not match that point. Useful options: timestamps (UNIX seconds per point), radiuses (max snap distance, one value per point — the default is only a few metres, so noisy GPS points usually need it), gaps ("split"/"ignore"), tidy, waypoints (indices to use as waypoints), and snapping ("default"/"any").
Trip
Visit a set of points in the fastest possible order (a travelling-salesman heuristic).roundtrip: false to change that, and source/destination ("any", "first"/"last") to pin the ends. trip.getAll also returns waypoints in the order the trip visits them.
Nearest
Find the road segment closest to a coordinate.number to get the second-, third-, … nearest segments; nearest.getAll returns all of them. The returned Waypoint includes the OSM nodes of the matched segment.
Geocode
geocode.search converts an address into coordinates, by free text or by structured fields (exactly one of the two):
results list simply means nothing matched. The client always requests format=json, regardless of the API’s default response format. Use filters (repeatable, e.g. countrycode:sg) to restrict results and bias (e.g. proximity:103.8,1.3) to prefer places near a point. GeocodeResult.location() returns a Point in the usual [longitude, latitude] order, ready to feed into routes, matrix, or optimization. Errors from the geocoding upstream are classified by HTTP status like any other failure (401 → UnauthorizedError, 429 → RateLimitedError, 502 → UpstreamUnavailableError).
Optimization
Assign tasks to a fleet and order each vehicle’s stops.shipments instead of jobs for pickup-and-delivery pairs that must be served in order by the same vehicle.
Health
The only call that works without an API key, which makes it a useful connectivity check.Error handling
Every API failure throws anApiError subclass. Classify it with instanceof rather than matching on message text:
Reach for
ApiError when you need the status code, engine code, or raw body:
The Python client names this classError; here it isApiError, because JavaScript already has a globalErrorand an exported class of the same name would shadow it.
Configuration
Invalid options throw a
TypeError immediately.
Cancellation and deadlines
Every call accepts an options object with asignal and a timeout:
timeout bounds the whole retry sequence, like a context deadline in the Go client; the constructor timeout applies to each individual attempt. When the deadline expires the call rejects with a DOMException named TimeoutError; aborting the signal propagates the abort reason unchanged.
Retries
Rate limits (429), server errors (5xx), and transport failures are retried with exponential backoff and jitter; aRetry-After header takes precedence when present. Other 4xx responses are returned immediately — they would fail identically on a retry and would still consume quota.
Things to know
Coordinates are [longitude, latitude]
This is the GeoJSON order, and the reverse of the “lat, lng” used by most map UIs. Swapped coordinates are usually caught locally — a longitude in the latitude slot fails the [-90, 90] check before a request is sent — but a swap that stays in range will silently route somewhere unexpected.
Coordinates must share a country
Every coordinate in a single request must fall within one country; the API routes each request to a per-country engine. A Singapore → Kuala Lumpur request fails withCrossCountryError.
Supported countries: Brunei, Cambodia, Indonesia, Laos, Malaysia, Myanmar, the Philippines, Singapore, Thailand, and Vietnam.
Plan limits
Exceeding a size limit returns
PlanLimitExceededError; exhausting the daily allowance returns QuotaExceededError.
Examples
Runnable programs live inexamples/:
Development
fetch — no network access and no API key.
Integration tests hit a live API and are skipped unless an API key is set:
