2026 · Live · Solo product
A live vessel tracking dashboard for the Singapore and Malacca Straits, tracking around 270 ships at a time from raw AIS radio. Its organising idea: never show a measurement and a crew's claim as though they were the same thing.

Selat is Malay for the strait, which is the whole scope: this covers one waterway, the busiest shipping lane on earth, rather than claiming an ocean. It listens to AIS, the radio system ships broadcast on, and turns it into an operations screen for port agents, chandlers and terminal planners. A Next.js 16 and React 19 front end draws the fleet on a MapLibre chart; behind it a Python MCP server holds the websocket, keeps a SQLite history and answers fourteen tools covering search, vessels near a port, tracks, port calls, anchorage clustering, traffic density, congestion and observed passage times across nineteen sea areas. The product argument is about honesty. AIS carries two kinds of information in one stream: position, speed, course and rate of turn are measured by instruments, while destination, draught and arrival time are typed in by the crew. Most trackers print all six in one table, which quietly claims a guess and a measurement are equivalent. Here the measured values sit in panels grouped by how fast they change, and the three the crew enters sit apart on amber under an Unverified heading. The same discipline runs through the rest: every sentinel that AIS uses for not reported is checked rather than passed through, so a draught of zero is absence and not a ship drawing nothing, and an IMO number is kept only when its check digit verifies. Absence is the normal case, since identity messages arrive far less often than position, so the interface says Not reported plainly instead of guessing. A position fix older than six minutes dims to amber, because that ship is no longer where her marker sits. Deployed as a single container behind a Cloudflare Tunnel.
TypeScript · Next.js · React · Tailwind CSS · MapLibre GL · Python · MCP · SQLite · WebSockets · Docker · Cloudflare Tunnel

