§1The problem
It all started as a single app that grew into a “superapp”: tasks, calendar, habits and goals in the same database and the same code. It became hard to change one part without breaking another, and other apps (health, dashboard) had to copy its data. There was no clear rule for who owns each piece of data.
§2What I built
- Golden ruleEach type of data has exactly one owner. Nobody keeps a copy.
- task-meTasks, lists and tags, with a kanban board.
- log-meActivities (what happened).
- plan-meCalendar, with its own events and read-only ICS calendars.
- habit-meHabits, with streaks, heat map, a “skipped” state and holiday pauses.
- note-meNotes in Markdown files (the source of truth), with links between notes and backlinks; the database is only an index.
- coach.meThe coaching app; it also owns the central catalogue of lists and tags the others use.
- data-hubHeadless broker between all of them: service registry, authenticated proxy, per-app tokens with scopes (read/write per service) and notification events. It never stores domain data. It has a console (Next app) to see events, services, apps and tokens.
- ask-meTakes voice or text commands from iPhone Shortcuts, interprets them with AI and routes them to the owning app (task, event, habit, note…), with history, “undo” and sharing from the iPhone menu.
§3The hard parts
6 entries- 01
Breaking up a big app without taking it down
A staged (strangler) migration: the old app kept running on adapters while each service was born; data was migrated repeatably and checked by counts.
- 02
A broker that owns nothing
During design I cut data collectors and ready-made “views” out of the hub. Screen composition stays in the consuming app.
- 03
Security by scope
App tokens with per-service scopes, hashed in the database, shown once; the console cannot revoke its own token.
- 04
Shared taxonomy
Lists and tags live in coach.me; the others store only the id and resolve the name on the fly.
- 05
Notes in files as the source of truth
A decision opposite to the other apps (SQLite first), so AI and git can read and write the notes.
- 06
Voice and text with AI in ~7-11 s end to end
With instant undo that doesn't call the model (measured in August 2026).
§4Result
- apps, one owner per type of data
- 8
- voice command, end to end
- ~7-11 s
All the apps run on my home server and I use them over a private network. They share the same branding and components. They are for my personal use only.
§5Stack
- Next.js 16
- React 19
- TypeScript
- Tailwind 4
- SQLite (better-sqlite3)
- Hono (hub engine)
- Own design system
- pm2
- Tailscale
- iPhone Shortcuts
- AI via command-line agent