The Problem
Building an interactive 3D bookshelf typically means wiring together Three.js scene management, animation state machines, and asset loading from scratch. This repo solves that by providing a complete, working React/Next.js application—a shelf of procedurally generated hardcover books with orbit/pan/zoom inspection—plus a vendored suite of agent skills for generating more Three.js apps and games. The core value is a forkable starting point where the hard part (motion, collision-safe poses, material handling) is already done.
What This Does
bookshelf is a Next.js app that renders a Three.js bookshelf. Catalog data in app/catalog.ts drives deterministic procedural cover art (app/cover-art.ts), with optional contributor-owned images under public/books/. The animation and layout logic lives in app/ShelfEngine.ts (1,398 lines) and app/book-motion.ts, which handle browse/focus poses, damping, and collision safety.
The repo also vendors the mint-threejs-skills suite under .agents/ (91 files), a collection of agent instructions, reference docs, and two standalone Three.js examples (asset viewer, gameplay systems). These are tooling assets, not part of the running app. The app itself is deliberately small: 10 code files in app/, 1 in worker/, and a few in tests/.
How It Is Wired
Execution starts in app/page.tsx, which mounts the React app. app/ShelfEngine.ts is the hub—35 functions, called from 1 other file, calling into 6. It defines the core helpers (damp, easeOutCubic, toTexture, createLivingMaterial) and routes everything through dispose (called from 9 places, the widest blast radius). app/book-motion.ts owns pose math (lerp called from 6 places) and app/cover-art.ts generates the procedural covers.
The only outbound network call is in worker/index.ts (a Cloudflare Worker with a fetch handler). Everything else is local rendering and asset loading. The import graph shows 56 internal modules, 41 edges, zero circular dependencies. The main risk is app/ShelfEngine.ts—a single change there ripples across the entire app. The vendored .agents/ examples are separate and isolated.
File-by-file map:
app/catalog.ts— book metadata and paletteapp/site-config.ts— collection-level brandingapp/ShelfEngine.ts— renderer, layout, input, animationapp/cover-art.ts— procedural cover generatorapp/book-motion.ts— pose and collision logicapp/stripe-assets.ts/stripe-foil.ts— optional asset adapterstests/rendered-html.test.mjs— server-render regression testworker/index.ts— the sole network effect
How To Use It
Setup (from README, requires Node.js 22.13+):
npm ci
npm run dev
Configuration: no environment variables required. Edit app/catalog.ts to add books, app/site-config.ts for branding. Optional cover images go in public/books/<book-id>/cover.webp.
Running it: npm run dev starts the Next.js dev server. Before submitting changes, run npm run check and npm run security:audit (both documented in the README).
Real-World Use
A publisher wants a public, interactive catalog of their titles. They fork this repo, replace the demo Stripe Press entries in app/catalog.ts with their own metadata, drop cover images in public/books/, and deploy to OpenAI Sites or any Next.js host. The procedural cover generator means even books without artwork render correctly. The worker/index.ts can be extended to proxy cover-art requests or serve catalog JSON from a CMS.
Code Health & Issues
Static analysis found 6 issues (3 high, 3 medium):
- High – Duplicated code: 37 repeated 6-line blocks across 10 files, mostly in the vendored
.agents/Three.js examples. Extract shared helpers. - High – Oversized files:
app/ShelfEngine.ts(1,398 lines),scripts/sync-mint-assets.mjs,app/cover-art.ts. Split by responsibility. - High – Deep nesting:
create_threejs_asset_viewer.test.pyhas max indentation depth 8. Use guard clauses. - Medium – No LICENSE at repo root (the vendored
.agents/has one, but the app doesn't). Add MIT or Apache-2.0. - Medium – CI exists (
.github/workflows/ci.yml) but never runs the 7 test files. Add a test step. - Low – Missing
.editorconfig,.gitattributes, formatter config. Add them.
Also: 4 dependencies are behind major versions (typescript, @types/node, eslint, vinext). No secrets committed, lockfile present.
The Bottom Line
The core app is well-architected for its size—no circular dependencies, clean separation of catalog/motion/render. The main technical debt is app/ShelfEngine.ts being too large and the CI not actually testing anything. The .agents/ suite is a large vendored dependency that adds noise but doesn't affect the app. Use it if you want a working Three.js bookshelf to fork; fix the CI and license before shipping.