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 palette
  • app/site-config.ts — collection-level branding
  • app/ShelfEngine.ts — renderer, layout, input, animation
  • app/cover-art.ts — procedural cover generator
  • app/book-motion.ts — pose and collision logic
  • app/stripe-assets.ts/stripe-foil.ts — optional asset adapters
  • tests/rendered-html.test.mjs — server-render regression test
  • worker/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.py has 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.