Build a 3D browser game or interactive scene that holds 60fps on integrated graphics and loads under 5MB.
Recommended stack
- Three.js + React Three Fiber - rendering. Declarative scene graph with React state; drei gives you controls, loaders, and helpers.
- Rapier (via @react-three/rapier) - physics. Fast WASM physics with a clean React binding.
- Blender + glTF - asset pipeline. glTF with Draco compression is the only sane 3D asset format for the web.
- Zustand - game state. Frame-loop-friendly state outside React's render cycle.
Build steps
- Start from
npm create vite@latest+ r3f; add a ground plane, a light, and one physics body before any assets. - Block out gameplay with primitive shapes; only replace with glTF models once the loop is fun.
- Keep game state in Zustand, read it in useFrame - never setState per frame.
- Compress models (Draco/meshopt), bake lighting where possible, target < 100 draw calls.
- Profile with r3f-perf on a low-end device; fix the top item only, repeat.
Watch out for
- Per-frame React re-renders - keep the frame loop out of component state.
- Unoptimized glTF files (10MB+ models) - compress and decimate early.
- Physics on everything; static geometry should be fixed colliders.
Definition of done
- 60fps on integrated graphics with r3f-perf overlay
- Total transfer < 5MB on first load
- Tab-away and tab-back doesn't break the simulation