Skip to content

For Developers

Architecture, contracts, and conventions for the IMMERSE platform.

If you're building Studio plugins, replacing Runtime, writing your own Node implementation, or just want to understand how the pieces fit together — start here.

Documents

  • ishow-schema.md — the .ishow file format (schema 0.5.0). What Studio writes, what Runtime reads.
  • node-protocol.md — HTTP wire protocol for IMMERSE Nodes (audio/video/GPIO).
  • runtime-api.md — Runtime's HTTP API for operator clients.
  • test-strategy.md — what tests exist, what they cover, what they deliberately don't.

Architecture in one diagram

┌────────────────────────────────────────────────────────────────────────┐
│                         DESIGNER'S LAPTOP                              │
│                                                                        │
│   ┌──────────────────────────────────────────────────────────┐         │
│   │ IMMERSE Studio (Electron app)                            │         │
│   │ ─ src/app.js              authoring UI, ~6500 lines      │         │
│   │ ─ src/index.html          window shell                   │         │
│   │ ─ main.js                 Electron main process          │         │
│   │ ─ src/preload.js          IPC bridge                     │         │
│   └──────────────────────────────────────────────────────────┘         │
│                       │ File → Save As                                 │
│                       ▼                                                │
│              ┌─────────────────┐                                       │
│              │  my_show.ishow  │  schema 0.5.0 JSON                    │
│              └─────────────────┘                                       │
└───────────────────────┬────────────────────────────────────────────────┘
                        │  rsync / USB / cloud
                        ▼
┌───────────────────────────────────────────────────────────────────────┐
│                       VENUE — TECH CLOSET                             │
│                                                                       │
│   ┌──────────────────────────────────────────────────────────┐        │
│   │ IMMERSE Runtime (Node.js, Windows mini-PC)               │        │
│   │ ─ src/runtime.js          entry point                    │        │
│   │ ─ src/show-state.js       loaded show + cue pointer      │        │
│   │ ─ src/validator.js        same rules as Studio           │        │
│   │ ─ src/executor.js         cue/clip fire engine           │        │
│   │ ─ src/dmx.js              sACN E1.31 transmitter         │        │
│   │ ─ src/gpio.js             HTTP→GPIO Node calls             │        │
│   │ ─ src/http-api.js         REST + dashboard server        │        │
│   │ ─ src/public/             web dashboard files            │        │
│   └──────────────────────────────────────────────────────────┘        │
│            │                       │                       │          │
│            │ sACN multicast        │ HTTP POST             │ HTTP GET │
│            │ universe 1..N         │                       │ /status  │
│            ▼                       ▼                       ▼          │
│   ┌──────────────┐    ┌──────────────────────┐    ┌────────────────┐  │
│   │ DMX fixtures │    │  IMMERSE Node      │    │ Operator tablet│  │
│   │ — chauvet,   │    │  ─ Node service entry  │    │ web browser    │  │
│   │   etc, etc.  │    │  ─ Request handler        │    │ http://10.../  │  │
│   └──────────────┘    │  ─ Media playback module│    └────────────────┘  │
│                       │  ─ GPIO control module                         │
│                       └──┬───────────────────┘                        │
│                          │ subprocess + GPIO writes                   │
│                          ▼                                            │
│                       Speakers / Screen / Relay                       │
└───────────────────────────────────────────────────────────────────────┘

The contract between pieces

Three contracts hold the platform together. If any of these change, the others break.

Contract 1: the .ishow file format

Studio is the only producer. Runtime is the primary consumer. The standalone validator script (tools/ishow-validator.js) is a third-party verifier.

When the schema changes: - Schema version bumps (0.5.0 → 0.6.0) - Studio writes a migration for the previous version - Runtime refuses files of an unknown version with a clear error - Validator updates to the new rules

Schema is documented in ishow-schema.md.

Contract 2: the Node HTTP protocol

Runtime is the only caller. IMMERSE Nodes are the only implementers. Documented in node-protocol.md.

When the protocol changes: - Both Runtime and Node services update in lockstep - Mixing versions is unsupported (no graceful degradation across protocol versions in v0.1.0) - A future version may add a /version endpoint and version negotiation

Contract 3: the Runtime HTTP API

Runtime is the only server. The web dashboard, custom operator clients, and any other surface (MIDI bridges, voice control) are consumers. Documented in runtime-api.md.

When the API changes: - Backward-compatible additions are fine (new endpoints, new fields) - Removed endpoints or changed response shapes are breaking changes — bump Runtime's major version - Dashboard is bundled with Runtime, so it always matches


Codebase conventions

Language

All three products are Node.js + vanilla JavaScript. No TypeScript, no compile step, no bundler.

The reasoning: - One language across the whole stack (Studio's renderer, Runtime, Node) — no context switching for developers - Trivial build: copy the source tree, npm install, run - Studio renderer must be vanilla JS anyway (Electron renderer process), so we made the rest match - Tests run with plain node test.js — no Jest, no Mocha, no setup

Code style

  • 2-space indentation, no tabs
  • Single-quoted strings
  • Semicolons mandatory
  • const by default, let when necessary, never var
  • Arrow functions for callbacks, named functions for module exports
  • Top-of-file file-level comment explaining what the module does and why
  • Comments explain why, not what

Testing

Each product has a test/ folder (or root-level test files for Studio) with vanilla node test runners. No assertion library — a simple ok(condition, message) function that prints "pass:" or "FAIL:".

Run tests: node test/run-all.js (Runtime, Node) or node looks_test.js etc. (Studio).

Test coverage at v0.1.0: - Studio: 790 tests across 13 files - Runtime: 55 tests - Node: 29 tests

See test-strategy.md for what's covered and what isn't.

Module exports

CommonJS. module.exports = { ... }. No ESM yet because some Node versions still don't handle the interop well and we have no reason to switch.

Error handling

  • Studio: errors caught and surfaced as notify(...) toasts. Uncaught errors written to log via electron-log.
  • Runtime: errors logged but do not crash the process. A bad cue should not kill the show.
  • Node: errors thrown as { code, message } objects, caught by the HTTP router, returned as JSON 4xx/5xx.

Logging

Three-level: info, warn, error. Plus fire (a custom level for cue firings — green in the terminal).

Log to file (rotated at 2 MB) and stdout. No remote log shipping in v0.1.0.


What's NOT in scope for this codebase

So you don't accidentally try to build any of these without checking:

  • A user account / login system — IMMERSE has no users in v0.1.0. Anyone with network access controls everything.
  • Multi-tenant cloud hosting — Runtime is single-tenant per venue.
  • A database — .ishow is a JSON file. State is in memory. No SQL anywhere.
  • TypeScript — see above.
  • A frontend framework (React/Vue/Svelte) — Studio renderer and Runtime dashboard are vanilla.
  • Build tooling beyond electron-builder (Studio) and pkg (Runtime). No webpack, no Babel, no Vite.

If you find yourself wanting any of the above, stop and ask first. Likely there's a simpler way that fits the existing architecture.


Where to find things

If you need… Look in…
Studio's main code immerse-designer/src/app.js
Studio's window setup immerse-designer/main.js
Studio's IPC bridge immerse-designer/src/preload.js
The .ishow schema immerse-designer/docs/SHOW_SCHEMA.md (reference copy here in this docs folder)
Sample .ishow for testing immerse-designer/docs/sample_show.ishow
Runtime's main code immerse-runtime/src/runtime.js
Runtime's executor (cue firing) immerse-runtime/src/executor.js
Runtime's web dashboard immerse-runtime/src/public/
Standalone schema validator immerse-designer/tools/ishow-validator.js