Skip to content
xanes.dev
All projects

In development

nexus

A no-code desktop app for generative visual effects — wraps TouchDesigner through a WebSocket bridge so creators can build real-time visuals without writing shader code.

Overview

Nexus is a no-code desktop app for generative visual effects. It wraps TouchDesigner — a professional node-based VFX engine — behind a clean UI, so creators can drive real-time visual templates and export short video clips without ever opening TouchDesigner or writing shader code.

Problem

TouchDesigner is enormously capable and enormously intimidating. For a creator who just wants a reactive visual for a clip or a set, the learning curve — node graphs, operators, shaders — is out of proportion to the goal. The power exists; the interface prices most people out of it.

Solution

Nexus talks to a running TouchDesigner instance over a WebSocket bridge. Templates live as .tox files on the TouchDesigner side; Nexus exposes their parameters as ordinary UI controls — sliders, pickers, toggles — and streams changes to the engine in real time. A capture manager handles exporting the result as a video clip. The creator never sees a node graph.

Architecture

It's an Electron app with a strict two-process split. The renderer (React + Zustand) owns the control panel, template selector, and export UI. The main process owns TDEngine — the WebSocket client that manages the TouchDesigner session — plus IPC handlers and the CaptureManager. The two sides communicate only through a contextBridge preload, and a shared contract package defines every message type crossing either boundary.

On the TouchDesigner side, a WebSocket DAT in server mode receives parameter updates and reports state back — so the engine integration is a protocol, not an embedding.

┌────────────────────────────────────────────────┐
│                  Electron App                  │
│  ┌──────────────────┐    ┌──────────────────┐  │
│  │ Renderer         │    │ Main             │  │
│  │ React + Zustand  │◄──►│ TDEngine         │  │
│  │ ControlPanel     │IPC │ CaptureManager   │  │
│  │ TemplateSelector │    │ IPC handlers     │  │
│  └──────────────────┘    └────────┬─────────┘  │
│        contextBridge (preload)    │            │
└───────────────────────────────────┼────────────┘
                                    │ WebSocket
                         ┌──────────▼──────────┐
                         │   TouchDesigner     │
                         │   WebSocket DAT     │
                         │   (.tox templates)  │
                         └─────────────────────┘

Tech stack

ElectronTypeScriptReactZustandWebSocketTouchDesignerVitepnpm workspaces

Challenges

  • Keeping three runtimes honest — renderer, main process, and TouchDesigner — required a shared contract layer; without typed messages, every protocol change broke something silently.
  • TouchDesigner session lifecycle: the app has to detect, connect to, and gracefully recover from an engine that the user starts, stops, and edits independently.
  • Real-time parameter streaming has to feel instant without flooding the WebSocket — batching and throttling controls without visible latency.

Lessons learned

  • Wrapping a professional tool beats reimplementing it — the WebSocket bridge gets TouchDesigner's full rendering power for the cost of a protocol.
  • A shared types package between processes is not optional in Electron apps; it's the difference between a protocol and a guess.
  • No-code UIs live or die on the quality of the parameter mapping — deciding which knobs to expose is product design, not plumbing.

Future improvements

  • A broader template library with richer parameter schemas.
  • Timeline/keyframe control over parameters, not just live values.
  • Longer-form export presets and codec options.