Today we're releasing @arcnautical/maritime-routing — the production routing engine that powers ArcNautical's voyage scoring product — as a free, MIT-licensed npm package. Zero dependencies. Source is on GitHub.
If you've ever tried to compute a believable ocean route between two ports in JavaScript, you know the gap. The existing open-source option (searoute-js) is unmaintained since 2020, uses pre-2010 coastline data, and routinely produces routes that cross land. The commercial APIs (Searoutes, ChartCo, sea-distances) charge between €600 and €6,900 per year and gate behind sales calls.
There is no good middle ground. We built one for our own product, hardened it against 1,790 real shipping routes, and now we're shipping it free.
What's in the box
- A* ocean pathfinding on a 0.05° resolution bitmap (7,200×3,600 cells) derived from OpenStreetMap. Routes are guaranteed to never cross land.
- Dijkstra waypoint routing through 48 strategic chokepoints — Suez, Panama, Malacca, Gibraltar, Hormuz, Bab el-Mandeb — with distance-weighted graph routing.
- 510+ ports in a UN/LOCODE-keyed database with coordinates, port type, and ocean region. Searchable by name, country, or code.
- Weather-aware speed model (Kwon 2008, Lu et al. 2015) — Beaufort-based speed reduction, per vessel type and load condition, direction-aware.
- EEZ transit analysis — detect which Exclusive Economic Zones a route crosses. Sanctions-flagging hook included.
- Avoid zones — route around piracy areas, conflict zones, or any user-defined polygon.
- GeoJSON output — every route is a
LineStringready for deck.gl, MapLibre, Leaflet, or your map renderer of choice.
A six-line example
npm install @arcnautical/maritime-routing
import { computeRoute, findPort } from '@arcnautical/maritime-routing';
const rotterdam = findPort('NLRTM');
const singapore = findPort('SGSIN');
const route = await computeRoute({
from: rotterdam,
to: singapore,
vesselType: 'container',
loadCondition: 'laden',
});
console.log(route.distanceNm, 'nm via', route.viaWaypoint);
// 8,288 nm via SUEZ_CANAL
That's the whole API surface for the common case. The advanced surface (raw A*, avoid-zones, EEZ inspection, weather sampling, per-segment ETA) is documented in the README.
What this library is not
Honest about scope:
- Not a fleet-tracking product. It doesn't ingest AIS. ArcNautical's commercial platform does, but that's a different stack.
- Not a live weather forecast. Beaufort-aware speed reduction takes a wind field as input; we don't ship one. Plug in Open-Meteo, ECMWF, or your provider of choice.
- Not a navigation system. Don't put it on a bridge. These are macro-scale planning routes (kilometre resolution), not chart-grade routes for piloting.
- Not a port-call optimiser. Optimal multi-stop routing, bunkering, and laytime modelling are deliberately out of scope.
What it does is the boring, hard, well-defined problem of "compute me a believable route between two real ports, faster than the commercial API, with no land crossing, and please make the code readable." We've used it in production for a year. The unit tests have caught every regression we've shipped.
Why open-source it now?
Two reasons. First, every shipping startup we know has reinvented this exact engine, badly. We have the data and the production hardening; nobody else needs to do the work again. Second, the maritime tooling ecosystem in JavaScript is anaemic — a healthier ecosystem helps everyone, including us. The product we sell sits a layer above (vessel dossiers, sanctions screening, voyage risk scoring); the routing engine is infrastructure.
If you want to use it: npm install @arcnautical/maritime-routing. If you want to contribute: github.com/SaltyTaro/maritime-routing. Issues and PRs welcome.
If you're building anything in the maritime tech space and need a sanctions screen, a vessel dossier, or a voyage risk score, that's what arcnautical.com is for. The routing engine is the open-source slice.