Skip to main content

Features

Everything you need to describe a 3D gallery as data and run it.

Serializable scene language

A space is plain data: walls, artworks, and a camera, in a single object that survives a JSON.parse(JSON.stringify(scene)) round-trip. No three.js, no functions — exactly what an editor or backend needs.

Walls as top-down paths

Draw a wall as a polyline footprint with a height and thickness. One continuous run of walls follows the path — no need to declare each side, and corners just work.

Artworks anchored to edges

Name any wall segment and hang a piece on it by position (units or %) and height (units, %, or the camera's eye level), on either face. Move the wall and the piece follows.

Free-roaming camera

A first-person camera you drive with the mouse and WASD or the arrow keys, with a subtle head-bob and boundary clamping. Ported from a real virtual gallery.

Hot reconciliation by id

Hand the engine a new scene and it diffs by id — only what changed is rebuilt. Add a wing or drop one while the visitor is walking, and the camera keeps its pose.

Framework-agnostic

The engine is vanilla three.js with a high-level ctx API; three.js stays an implementation detail. Use it directly, or with the React bindings and a declarative <Gallery> component.

A DOM overlay (HUD)

Layer controls and visual aids over the canvas with a slot-based overlay. Optional daisyUI widgets out of the box, or bring your own component with a single (ctx) => HTMLElement.

Tree-shakeable & typed

Small packages — core, engine, props, overlay, react — so you only pay for what you use. TypeScript throughout, strict mode, ESM and CJS builds.