installable pwa · independent
kochi water metro
an offline-first companion for a ferry ride: the route map, plus a bilingual story that surfaces as each place drifts past.
- role
- design + build
- context
- independent, unaffiliated · kochi water metro
- year
- 2026
about
kochi's water metro crosses backwaters most apps render as blank blue. this is an independent, non-commercial companion built on the official public map: pick a boarding terminal and a destination, and a journey plays out on its own.
the ferry animates along the real water channels, its status cycles from boarding to arrived, and photos and stories surface as each place passes. full english and full malayalam, narration included.
credits
- design, build, bilingual content
- evana sajan
- stack
- vanilla js · service worker
- base map
- official public asset, attributed
- photography
- creative commons, credited
try it
open full screenpick a boarding terminal and a destination, press begin, and then stop touching it. the toggle at the top right switches the whole thing, narration included, into malayalam.

product thesis
you do not really need navigation on a ferry. there is one route and someone else is steering. what you might want is something telling you what you are passing.
why this one is different
a transit app assumes you are trying to get somewhere and are late.
on a ferry you have already arrived at the only decision there was.
so this one spends its whole interface on the window, not on the route.
the systems thinking
map
the official public route map, attributed, with hand-traced channel geometry over it so the ferry never crosses land.
journey
you choose two terminals and the ride drives itself. status cycles boarding, under way, arrived; the interface reflects rather than waits for input.
stories
each terminal and each stretch of water carries a landmark story and a waterway story, surfaced by position rather than by tapping.
language
malayalam is the language of the place, not a translation of the english. every story, fact and label exists twice, and the narration doubles.
offline
map, photos, fonts and narration are cached up front. zero external requests, and the malayalam webfont is bundled rather than fetched.
key design decisions
no buttons to press
why
you are on a boat with a phone in your hand, not at a desk. an interface that needs attention competes with the thing it is describing.
tradeoff
you give up fine-grained control. you cannot skip ahead, scrub, or pull up a place you already passed.
result
you choose a journey, then put the phone down. the ferry drives, the interface reflects, and the stories arrive on their own.
assume there is no signal
why
mid-river is exactly where a connection drops, which is also exactly when the next story is due.
tradeoff
everything has to be cached up front, so the first load is heavy and the content cannot be updated without a new install.
result
an offline-first install caches the whole experience, narration included, and a single missing file never breaks the journey.
bilingual as equals, not as a setting
why
a malayalam mode that is a thinner version of the english one tells a local reader exactly what the product thinks of them.
tradeoff
twice the content to write, twice to keep accurate, and a recorded narration in both rather than one.
result
the two versions are the same product. the font is bundled so malayalam never falls back to a system face, and the narration has a timed read-along fallback in both languages.
edge cases accounted for
a terminal that is not on the route
the network is a real graph rather than a list, so an impossible pair cannot be chosen and a journey with a change on the way is described as one.
the connection dropping mid-river
the whole experience is cached before the ride starts, so losing signal halfway is indistinguishable from not losing it.
a missing photo or narration file
a single absent asset degrades to its story text rather than failing the journey. an offline app that breaks on one 404 is not an offline app.
a malayalam font that never loads
bundled rather than fetched, because a system fallback for malayalam is usually no malayalam at all, and the read-along fallback covers narration that will not play.