case 03 / 06 · Own product · transit app (PWA)
role
Solo developer · product, design & build
year
2026 · 3.5 weeks
stack
React + TypeScript · Tailwind CSS · Supabase (Postgres + Realtime) · Netlify Functions + scheduled jobs · Web Push + installable PWA · GTFS open data
links




Live status for all six Klang Valley LRT/MRT lines on one screen, from official Rapid KL notices and one-tap rider reports.
## 01
Problem
Klang Valley rail riders find out about delays late. Rapid KL posts notices on its website, often only in Malay, and during long incidents it may update just every one to two hours. If you’re standing on the platform, nothing tells you in one place whether your line is delayed, disrupted or back to normal.
## 02
Research
The design was shaped by how Rapid KL actually posts updates. Notices often go quiet for hours mid-incident, so the app waits up to three hours before assuming an incident is over. After launch I deliberately cut features (likes, photos, free-text notes and extra news sources) to keep only signals that are trustworthy and need no moderation. I ran a UX, accessibility and motion audit with before/after comparisons. I ride the Kelana Jaya line daily and kept getting caught out.
## 03
Design
A board of six line cards. Lines running normally collapse to one row, so all six fit on one phone screen. Each line has a bookmarkable page with a vertical station map: affected stations glow red, and tapping a station filters the reports. Reporting takes two taps (issue type plus optional station), with no free text, so there’s nothing to moderate. Riders can tap “Running fine” to close an incident early, get push alerts when a followed line changes status, and see alternative routes. Light, dark and system themes, and motion respects reduced-motion settings.
## 04
Build
A React single-page app on Netlify with a Supabase Postgres backend. Each line’s status is calculated from a weighted score of rider reports, with official notices setting a minimum level. Scheduled jobs refresh status every 5 minutes and check Rapid KL’s public notice feed more often at peak hours. If the official source stops responding, the board says so instead of wrongly showing “all clear”. Push alerts are claimed in a single database transaction, so a rider never gets the same alert twice. Old data is deleted automatically after 48 hours.
6
rail lines covered
2 taps
to report an issue
260+
automated tests
48h
data retention, privacy by design