Lab
A collaborative grocery app for two. Shared lists plus a price book that normalises everything to $/100g — so sale prices and different pack sizes are comparable at a glance. Built with Expo so it runs natively on both our phones.
A recipe site with ingredient scaling, nutrition tracking, and a cooking mode that keeps the screen on. Recipe apps have too many ads and none of them scale fractions correctly. Recipes are markdown files; Keystatic is the editor.
A reference catalogue of equipment across Anytime Fitness gym locations in Singapore. Built from personal frustration with arriving at a gym that didn't have the rack I needed. Equipment is hand-curated as JSON and grouped by function.
A personal bookkeeping app that replaces spreadsheets. Imports bank statements, parses them into a SQLite ledger, and produces categorised reports. Locally it's a Python server against real data; the live site serves fictional demo data.
A personal activity analytics dashboard built on my gym visit data. This parses and visualises the data: monthly trends, time-of-day heatmaps, membership pauses.
A deterministic workout generator built for one athlete: me. Workout apps optimise for everyone, which means they work for no one in particular. This one encodes a specific rotation, equipment access, and fatigue logic. Fully client-side, no API.
Anyone can ship an app right now. Not everyone governs what they've built.
Schema owns the data model, design tokens own the visual layer, docs own the workflow. Anything duplicated drifts.
Stale references and obsolete docs mislead more than missing ones. Gaps compound quietly.
Remove structural weaknesses before they become load-bearing. Good systems get easier to change over time, not harder.
Data shape issues belong in the schema, not patched in the UI. Style decisions belong in the design system, not inline.
A precise MVP with an explicit deferred list prevents accumulation. What you leave out matters as much as what you ship.