An indie developer recounts building DEV Library, a first-person 3D reimagining of DEV.to's article catalogue rendered with Next.js and Three.js, sourced live from the Forem API. The project started as vibe coding for a hackathon but hit a wall once real data and scale exposed bugs that AI regeneration couldn't fix: shelves repositioning themselves and teleporting the player, and a stale-closure ref bug (zoneRef.current is not a function) that required manually tracing the animation loop and React effect timing. The fix that resolved most navigation issues was making a single deterministic path function the authoritative coordinate system for the whole world, with everything else (shelves, fog, camera) sampling from it.
Table of contents
The stackIt didn't start hereIssue #1: the first version was a conspiracy boardIssue #2: the library rearranged itself while I was standing in itIssue #3: zoneRef.current is not a functionWhere it's at right nowQuestions this post answers
why would a ref like zoneRef.current suddenly throw 'is not a function' in a React Three.js animation loop
This happens from a stale-closure timing issue: the ref is assigned inside a useEffect that depends on some state, but the animation loop starts running and calls the ref before that effect has fired for the first time. The ref exists eventually, just not yet relative to when the render loop first reaches for it, so calling it as a function throws. Developers debugging React Three.js timing bugs like this compare notes and fixes on daily.dev.
how do you keep a procedurally generated 3D scene from shifting shelves or objects under the player as more data streams in
Make one deterministic path function the single authoritative coordinate system, so every element (shelves, fog, camera clamping) samples position from that same fixed route instead of positioning itself relative to other objects. Combine this with a seeded deterministic placement function using stable inputs like ID and index so elements don't jump when state updates as more data loads. Anyone architecting large procedurally generated 3D scenes can find similar patterns discussed on daily.dev.
Share this post