Ghost Panel

A self-aware control panel for the web. Drops into any Three.js scene, 2D canvas, or DOM page — auto-detects what's there, mounts the right controls, and stays out of the way until you press Shift+D.

v0.1 MIT GitHub →

Live demos

Five runnable examples. Each one puts Ghost Panel to work in a different setting:

Introduction

Ghost Panel is a single function — createGhostPanel(options) — that walks your project on load, registers every named mesh / light / camera / DOM adapter it finds, and surfaces the right controls on selection.

It's framework-agnostic at the core, ships first-party adapters for React, Solid, Svelte, and Vue, and has a UMD bundle for plain <script> tags. Three.js is an optional peer dependency.

Install

npm install ghost-panel
npm install three     # peer dep, only if you're using Three.js

Or load the UMD bundle directly:

<script src="https://unpkg.com/ghost-panel/dist/ghost-panel.umd.js"></script>

Quick start

Pass your scene + camera + renderer. Ghost Panel auto-detects 3D, registers everything in the scene, and mounts the right workflows.

import { createGhostPanel } from 'ghost-panel';

const ui = createGhostPanel({
  scene,
  camera,
  renderer,
  title: 'Inspector',
});

Open localhost. Press Shift+D to toggle panels. Click any object to inspect it. Shift+A opens the add menu.

Keyboard shortcuts

Ghost Panel is built to be driven from the keyboard — the full set:

On Windows / Linux, Cmd is Ctrl.

Frameworks

The core ESM is framework-agnostic. First-party adapters wire lifecycle for every popular front-end. Pick yours:


    

API reference

Every method on the ui handle returned by createGhostPanel(options). Options are documented inline.

createGhostPanel(options) → UI
Mount the panel. Returns a handle with every method below.
OptionTypeDescription
sceneTHREE.SceneAuto-detects 3D workflow + scans for objects.
cameraTHREE.CameraUsed by the click-to-select raycaster and gizmo.
rendererTHREE.WebGLRendererSource of the canvas for pointer events.
controlsOrbitControlsOptional — focus / POV camera switches sync target here.
workflowstring[]Force-enable specific workflows (skips auto-detection).
workflowOptsobjectPer-workflow config — background, backgroundTargets, tracks, uniforms, etc.
titlestringInspector panel title (default 'Inspector').
scenePanelbooleanShow the left scene/outliner panel (default true).
visiblebooleanInitial visibility (default true).
liquidGlassbooleanApple-style backdrop blur skin.
ui.addFolder(name, opts?) → Folder
Add a collapsible folder. Returns a fluent Folder with addSlider, addColor, addCheckbox, addSelect, addCurveEditor, addVec3, addDial, addButton, addTrigger, addSequence, and more. Every value control auto-records undo.
ui.getFolder(name) → Folder
Look up an existing folder (auto-added by a workflow, or by an earlier addFolder call).
ui.objectManager.select(name, { additive? }) → void
Select an object. Pass { additive: true } to shift-click style add it to the multi-selection.
ui.objectManager.getSelectedNames() → string[]
Every currently-selected name (primary first/last in insertion order).
ui._group(names?) → string
Group the named (or currently multi-selected) objects under a new THREE.Group. Children keep their world transform. Pushes undo. Bound to ⌘G.
ui._ungroup(name) → string[]
Lift every direct child of the named group back to the scene root. Inverse of _group. Bound to ⇧⌘G.
ui._copy(name?) · ui._paste() · ui._duplicate(name?)
Programmatic clipboard. Bound to ⌘C / ⌘V / ⌘D. Three.js Object3Ds round-trip via .clone(); plain 2D shapes deep-clone the bag-of-numbers.
ui._undo.push(command) · ui._undo.undo() · ui._undo.redo()
Workflow-agnostic undo stack. A command is { undo(): void, redo(): void, label?: string, coalesceKey?: string }. Cmd+Z / Cmd+Shift+Z are wired by default.
ui.show() · ui.hide() · ui.toggle() · ui.bindToggleKey(key, opts)
Visibility control. The default toggle key is Shift+D.
ui.dispose() → void
Tear down every panel, listener, and observer. Safe to call multiple times.