scenography
scenography is a library for building declarative 3D art galleries on top of a three.js engine. You describe a space as plain data — walls, artworks, a camera — and the engine materializes it and runs it.
It was born to power virtual galleries like jllizaur.art, but it is designed to be reusable anywhere.
Core principle: data vs. runtime
The single most important rule. Two layers, never mixed:
- Definition = pure data. Fully serializable to JSON. No three.js, no
closures, no functions. This is what an editor produces, what a database
stores, what travels over the network. It lives in
@scenography/core. - Behavior = code. Triggers, scripts, render logic. Registered by
reference and connected to the data by
id— never embedded inside the definition. It lives in@scenography/engine.
A scene definition must always survive a JSON.parse(JSON.stringify(scene))
round-trip unchanged.
import { defineScene } from '@scenography/core';
// Layer 1 — DATA. Serializable.
const scene = defineScene({
walls: [
{
id: 'room',
path: [
[300, -300],
[-300, -300],
[-300, 300],
],
edges: [{ segment: 0, name: 'north' }],
},
],
artworks: [
{
id: 'lucho',
location: { type: 'wall', edge: 'north', position: '50%' },
src: '/lucho.jpg',
size: [120, 160],
},
],
camera: { start: { position: [0, 170, 0] } },
});
import { createGallery } from '@scenography/engine';
// Layer 2 — CODE. Wired by id, uses the runtime.
const gallery = createGallery(scene, { canvas });
gallery.start();
The packages
| Package | What it is |
|---|---|
@scenography/core | The scene language: serializable data + validation. Zero three.js. |
@scenography/engine | The runtime: materializes a scene with three.js and runs it. |
@scenography/props | Optional, tree-shakeable catalog of set-dressing objects. |
@scenography/overlay | A framework-agnostic DOM overlay (HUD) layered over the canvas. |
@scenography/react | React bindings: a declarative <Gallery> component. |
Continue with Installation and the Quick start.