Case study · 2026 · AI · Web · Mobile
Video demos break on the train, and a single camera angle never tells you what your hip should do.Built a 3D-rig engine where every exercise rotates with you - and the same engine runs on web and native.
AxisFit ships as a Next.js web app and an Expo native app off a single TypeScript engine that animates a bone-rig per keyframe set. Every exercise - squat, deadlift, push-up, pull-up, plank, lunge - is one set of keyframes, and the engine handles the grip, the ground alignment, and the hang. Adding a new exercise touches one file and goes live on web, iOS and Android together.
- Next.js
- React Three Fiber
- Expo
- TypeScript
- Three.js

Inside the build



Overview
- 10+
- 3D-rigged exercises shipped
- 1
- Animation engine
- 3
- Surfaces · web + iOS + Android
- 0
- Video files in payload
AxisFit is a fitness app where every exercise plays as a 3D-rigged figure you can rotate. The same animation engine drives the Next.js web app and the Expo native app, so a new exercise is one set of keyframes for both surfaces. Workout plans, the exercise library, and a progress dashboard ship on day one.
What shipped
What it does
- 3D-rig exercise animations · web + native, one engine
- Workout library + workout player + progress dashboard
- A single content set drives both surfaces
- Bone-aware grip + ground/hang alignment per rep
The problem
- Video demos break on phones with poor reception
- Form cues are hard to read from a single camera angle
- Two parallel codebases for web + native doubles every change
Why it matters
- Every exercise is rotatable and offline-ready
- Form reads from any angle the athlete picks
- One engine, one content set · ship features in one place
How it shipped
- 01 · BRIEF
Pin 'every exercise is 3D, no video' - and one engine for both surfaces.
Decision the project rested on: same engine on the web and on the phone, so a new exercise is one keyframe set instead of two parallel implementations.
- 02 · BUILD
Extract the rig engine into a shared package, drive both surfaces from it.
@axisfit/shared holds the engine, exercise metadata, sample plans, the progress contract. Native renders through expo-gl + expo-three; web renders through react-three-fiber. Both surfaces hand a rig + scene to the same ExerciseRunner, which lerps keyframes, ground-/hang-aligns the body and applies grip orientation.
- 03 · SHIP
Library, player, dashboard - live on web, iOS and Android.
Three surfaces went out the door at the same time on the same engine. Adding a new exercise - keyframes only - deploys to all three.
Stack
Engine
Keyframe-driven bone-rig
mapBones · applyPoseFrame · doGroundAlign · ExerciseRunner - the engine is shared TypeScript, no duplication between web and native.
Library
10+ exercises on day one
Squat, deadlift, push-up, pull-up, plank, lunge - and the equipment around them, built locally per surface so the engine stays equipment-agnostic.
Player
Workout flow with progress
Plan → set → rep with a per-frame ticking rig; native uses a PanResponder orbit camera so the athlete picks the angle that helps.
Dashboard
Session log + summary
SessionEntry + summarize() with a pluggable Storage interface - localStorage on web, AsyncStorage on native, the same contract.
Case study
“Every fitness app we'd seen was either flat illustrations or a single-camera video that breaks on the train. The team built one where the body is a 3D model you can rotate on the screen, and the same animation plays on the website and the phone app - both shipped at once. Adding a new exercise takes minutes, not a separate video shoot.”
More work
Next project
BetEdge