Update: Helbus is no longer available — HSL has since launched its own official real-time tracking app. We take that as the strongest possible validation: the problem was real, and we were solving it before the authority itself did. At its peak Helbus ranked in the top 10 of the App Store travel category in Finland.
The Problem
Helsinki's public transport (HSL) is reliable on paper, but the timetable is a statistical average, not a guarantee. Most of the time, that is fine. The experience breaks down at the edges — a dark, −20 °C winter morning in a suburban area, a weekend schedule with 30-minute headways. Miss the bus by two minutes because it departed early, and you are standing in the cold for half an hour. That is not a minor inconvenience; it is the kind of friction that erodes trust in public transit and pushes people toward cars.
The frustrating part: HSL already had the real-time vehicle position data, streamed over MQTT. The data existed. No consumer-facing product was built on top of it.
Identifying the Gap
Started by mapping the landscape. HSL's Journey Planner gave route suggestions based on static schedules. The Digitransit platform exposed GTFS feeds and a GraphQL API for stop/route metadata. The real-time vehicle positions, however, were only available through a raw MQTT topic — useful if you were a developer staring at a terminal, useless if you were a commuter at a bus stop.
The gap was clear: scheduling data and live positioning data existed in separate silos, and no product stitched them together for the end user. The opportunity was to build that bridge — a lightweight app that answers one question: where is my bus right now?
Technical Decisions
Real-time data pipeline. We subscribed directly to HSL's MQTT broker for vehicle positions. MQTT's pub/sub model gave us push-based updates with low latency, but it also meant handling bursty, high-throughput messages across hundreds of vehicles. We wrote a lightweight Node.js ingestion layer that filtered, deduplicated, and relayed only the positions relevant to a user's current view.
Cross-platform from day one. The web app was built with React and Redux — fast to iterate on, easy to deploy. For mobile we chose Flutter, which was still young at the time. The bet paid off: a single Dart codebase gave us both iOS and Android with native performance, and the hot-reload cycle kept our iteration speed high.
Backend glue. Firebase handled auth, push notifications, and some ephemeral state. A set of cron jobs kept route and stop metadata in sync with HSL's GTFS feeds. An admin dashboard (built in AngularJS, our legacy starting point before migrating the user-facing app to React) let us monitor data freshness and flag anomalies.
Design. All UI work was prototyped in Sketch. The core interaction was a map with a single affordance: tap a stop, see approaching buses with live ETAs. We deliberately avoided feature bloat — no trip planning, no ticketing, just the real-time answer.
Architecture at a Glance
- Data source: HSL MQTT broker (real-time positions) + Digitransit GraphQL (routes, stops, schedules)
- Ingestion: Node.js service subscribing to MQTT topics, filtering by geographic bounding box
- Web client: React / Redux, map rendered with Leaflet
- Mobile client: Flutter (iOS + Android)
- Backend services: Node.js, Firebase (auth, push, Firestore)
- Ops: Cron jobs for GTFS sync, admin dashboard for monitoring
Impact
- Ranked top 10 in the travel category on the Finnish App Store
- Hundreds of active users and community supporters
- Covered web, iOS, and Android — reaching commuters on every platform
- Demonstrated that a small team can ship a civic-tech product that meaningfully improves daily life, using nothing but publicly available open data
Reflection
Looking back, the biggest lesson is not about the code. It is about picking the right problem. When a side project solves something people actually feel every day, the impact can be surprisingly big for a small team. HSL eventually shipped their own version — honestly I see that as a win, not a loss. It means the problem was real and worth solving.
On the engineering side, this project made me touch almost everything — real-time data, mobile, web, backend, design, ops. That is rare for a single project, and it was a lot of fun.
Links
- Demo video (iOS/Android): YouTube