Dev Patel
Artifact JAN 2026Source

Epiphany & ShakeRage

Two SwiftUI apps built back to back — one widget-first capture tool, one motion-driven SceneKit game.

Classification
Artifact
Client
Personal
Window
NOV 2025 → FEB 2026
Duration
3 MO
Status
Shipped
The problem

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

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

Measured

2apps shipped
1shared auth layer
SwiftUIfirst native build
  • 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

Plan

5 items · scale 1:1
EPIPHANYWidgetKit capture1SHAKERAGESceneKit · CoreMotion2SWIFTUI APP LAYERshared components3SUPABASEauth + sync4POSTGRESQLstorage5
Note · Two very different clients over one shared identity and storage layer.
What I'd redraw

What 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.

Materials

Materials

SwiftUIWidgetKitSceneKitCoreMotionSupabasePostgreSQL