Reference guide
How it is built
The parts of the codebase, what runs where, and the rules that keep rendering correct.
Stack
An Electron desktop app with a Vite, React and three.js editor. Product views are path traced on WebGPU with three-gpu-pathtracer. State is kept with zustand. The local API is plain Node.
Two processes
| Part | Where | What it does |
|---|---|---|
| Editor | src/ | Everything on screen: the ad set, layers, inspector, chat, 3D views |
| Local API | desktop/server.cjs | Reads the product and packaging libraries, calls outside services, writes exports |
The same local API serves the Vite dev server and the Electron app. The packaged app uses a bundled copy built with npm run build:server into dist-desktop/.
Inside the editor
| Folder or file | Contents |
|---|---|
src/components/ | TopBar, LeftPanel (Layers, Products, Packaging), the ad set stage, Toolbar, Inspector, Chat, Settings, ArtworkDialog |
src/layers/ | The layout document: text, shape, vector, image and group layers with a frame per size. Undoable store, text layout, SVG and Canvas rendering, alignment and snapping, shortcuts |
src/ai/ | The Claude agent loop, system prompt, and the tools that edit the ad |
src/scene/ | three.js product views, camera poses, synced crops, thumbnails, packaging materials |
src/store.ts | Camera, product and background state, persisted |
src/actions.ts | Photoroom backgrounds, Arrow 2 vectors, product placement, compositing, export |
What the local API serves
| Route | Purpose |
|---|---|
| Product library | Reads /Volumes/MAKER_DEVELOPMENT/LIBRARY. Override with AD_SHOTS_LIBRARY |
/api/packaging | Lists the packaging models. Override the folder with AD_SHOTS_PACKAGING |
/api/ai/messages | Claude, through the Anthropic SDK |
/api/vector/generate, /api/vector/vectorize | QuiverAI Arrow 2 |
/api/photoroom/background | Photoroom background around the product |
| Reference images | OpenAI or Google, chosen in Settings |
| Export | Writes to ~/Downloads/Ad Shots Exports |
Where data lives today
Everything is on the user's computer.
| Data | Location |
|---|---|
| Products | A folder on disk |
| Packaging models | packaging/out, built GLB files |
| Artwork placed on models | The app's local database (IndexedDB ad-shots-artwork) |
| API keys | Operating system secure storage |
| Exports | Downloads |
The launch plan moves ads and products into an account. See Accounts and library.
Rendering rules worth knowing
- Keep three.js out of dependency pre-bundling. Both Vite configs do this. Two copies of three.js break the path tracer's shaders.
- A WebGPU canvas only holds its picture for the frame it was drawn in. Copy from it right after
renderSample. SeeProductView.present. - Use the WebGPU tracer. The older WebGL tracer rendered clearcoat black on a cold shader compile. On WebGPU, clearcoat and solid tinted glass render correctly.
- Packaging materials.
src/scene/packaging-materials.tsturns a model's named materials into realistic ones using texture sets inpublic/materials, and gives every print surface its own placeholder artwork. Library materials use no clearcoat and thin-walled glass by default; both can be set per model in Packaging Review.
The original Product Booth
The first app lives at /Volumes/MAKER_DEVELOPMENT/DEV/Apps/Product Booth. It is a native macOS app with Blender running headless as the render engine. Treat it as reference only: read it for ideas, do not edit, build or import from it.
Updated 2026-11-14. Built 2026-11-15.