Epiphany & ShakeRage
Two SwiftUI apps built back to back — one widget-first capture tool, one motion-driven SceneKit game.
The problem
I had written a lot of backend and very little native mobile. Two apps in one push was a deliberate choice: one that lives mostly outside the app, and one that is nothing but the app.
What I built
Epiphany is built around WidgetKit — the point is capturing a thought from the home screen without opening anything. That constraint decides the data model: writes have to be cheap, sync has to be tolerant of an app that is barely ever foregrounded.
ShakeRage is the opposite. CoreMotion drives gameplay through a SceneKit scene, so the work is all in the frame budget and in making physical motion feel fair.
Both sit on the same Supabase and PostgreSQL auth layer, which is the part I would actually reuse.
Measured
- Both apps shipped from an empty Xcode project inside one development cycle.
- WidgetKit capture path works without foregrounding the app.
- Shared Supabase auth means a second app cost a fraction of the first.
Plan
Plan
5 items · scale 1:1What I'd redraw
Sharing an auth layer across two apps with genuinely different session needs was the right instinct and the wrong abstraction — a game session and a capture session want different lifetimes. I'd split the token handling and keep only the identity layer common.