WGHTLFT is a native iOS weightlifting tracker backed by a Rails 8 API. The split is conventional but opinionated: the backend is a full Rails app, not --api mode, so the admin panel, dashboards, and marketing landing page all live in one codebase, while the mobile client talks JSON over a versioned Api::V1 namespace.
Auth runs through Devise + devise-jwt with 30-day tokens and a denylist revocation strategy; serialization goes through jsonapi-serializer so payloads stay predictable as the schema evolves. Postgres handles the data, and I leaned on deeply nested writes for things like workout sessions: a single request creates a session, its exercise entries, and every set log in one round trip. That kept the iOS networking layer thin and made the server the source of truth for validation.
The SwiftUI client has no third-party UI frameworks; every view is native SwiftUI, following a monospaced, high-contrast design language inspired by Nothing’s visual system. The 3D equipment visualization is the part most people notice first: when you punch in a weight, the app shows an animated barbell that loads plates onto itself to scale, with correct diameters and color-coding. It also handles dumbbells, kettlebells, and cable stacks as alternate modes.
The whole thing is built directly on SceneKit rather than pulled in from a 3D library. Building it natively meant tighter integration with SwiftUI’s animation system, so plate configurations animate when you change the weight, and a rotation gesture can spin the bar in 3D. Fewer dependencies, better behavior, and I have received a ton of compliments on that part of the app!
The program selector is a hand-rolled card stack, a swipeable deck with a tap-to-flip reveal showing each program’s full workout breakdown. I evaluated a few off-the-shelf card-deck libraries, but each one would have needed enough wrestling with gesture conflicts, theming, and state sync that rolling my own ended up cheaper.
The custom version handles drag-to-reorder within the stack, a lift/flip/drop animation sequence, per-card jitter for that “stacked deck” texture, and clean cancellation if the user interrupts mid-gesture. It is one of those pieces where the upfront build cost paid itself back the first time I wanted to tune a spring curve instead of fighting someone else’s API.
Rounding things out, there is an Apple Watch companion app, Siri shortcuts for logging sets by voice, Sentry for crash reporting, and the backend deploys to a single Dokku host via git subtree push from a monorepo. The stack is deliberately boring: Rails on the server, native frameworks on the client side, and custom only where custom earns its keep.
You can check out WGHTLFT for free on the App Store.