Skip to content

Architecture

Nuclei is three processes pretending to be one app: a Rust shell, a React frontend in the shell’s WebView, and a Python kernel subprocess. The frontend never touches Python directly — everything quantum goes over a localhost WebSocket. Dirac (the AI layer) never touches a Nuclei server — the frontend calls api.anthropic.com directly with a user-supplied key.

Nuclei architecture: the Tauri shell spawns the Python kernel; the frontend talks to the kernel over WebSocket, to the shell over IPC, and to api.anthropic.com directly; the kernel fans out to framework adapters and hardware providers.

LayerCodeResponsibilities
Tauri shell (Rust)src-tauri/Spawns and supervises the kernel process, manages the per-user Python venv, file system access, typed IPC commands, auto-updater, native menus
Frontend (React + TypeScript)src/Monaco editor, D3 circuit diagram, Three.js Bloch sphere, histogram, Dirac chat, Zustand stores. Also ships as the browser build — see desktop vs web
Python kernelkernel/WebSocket server, framework detection, adapters that normalize circuits to CircuitSnapshot, simulation, hardware submission
  1. You type in Monaco. After a debounce (default 300 ms, configurable in Settings → Kernel), the frontend sends {type: "parse", code, language} over the WebSocket.
  2. The kernel resolves an adapter — explicit language hint first, then regex detection on the source (Q# syntax is checked before Python imports) — and extracts a CircuitSnapshot: gate list, qubit count, depth. No simulation runs on parse.
  3. The frontend re-renders the circuit diagram from the snapshot. This loop runs on every pause in typing.
  4. On Cmd+Enter (Ctrl+Enter), the frontend sends {type: "execute", code, shots, language}. The kernel runs the full simulation and replies with a SimulationResult — statevector, probabilities, sampled counts, per-qubit Bloch coordinates.
  5. The Bloch sphere and histogram panels update from the result.

Message-by-message detail lives in the Kernel API reference.

  • Spawn. On startup the shell runs ensure_kernel_runtime: create the managed venv if missing, rebuild it if its Python is older than 3.10, install the kernel’s import-time deps (websockets, numpy, keyring) if absent — then launches kernel/server.py with the venv’s interpreter. If the venv can’t be bootstrapped it falls back to system python3. See install & build for the venv lifecycle.
  • Port. The kernel binds localhost and prints exactly one ready line to stdout: Nuclei kernel ready on ws://localhost:<port>. Standalone embedders should parse that line — the kernel scans 9742–9761 if the default port is taken. The desktop app instead pins 9742, because the frontend’s WebSocket URL and the CSP both hardcode it. Before spawning, the shell reaps only a leftover kernel that Nuclei itself recorded; if anything else holds the port it refuses to start rather than kill an unrelated process.
  • Authentication. Every connection must pass a loopback Host check, an Origin allowlist and a first frame {"type": "authenticate", "token": ...} carrying a per-launch token (constant-time compare, never in the URL). The desktop shell generates the token and hands it to the frontend; a kernel started without a token refuses to run unless NUCLEI_KERNEL_INSECURE_DEV=1 is set. Unauthenticated or forbidden connections are closed with 4401 / 4403.
  • Connection. JSON text frames, 1 MiB inbound cap, WebSocket ping every 30 s with a 20 s pong timeout.
  • Isolation. Each connection gets its own Executor — parse/execute state never bleeds between clients. The HardwareManager (provider connections, job registry) is deliberately process-global, shared across connections.
  • Logging. Kernel stdout/stderr are drained into the shell’s log file, so a kernel crash leaves a trace (see configuration for log paths).
You want toTouchGuide
Support a new quantum frameworkkernel/adapters/ + the Rust catalogFramework adapters
Submit to a new hardware cloudkernel/hardware/Hardware providers
Drive the kernel from outside Nucleinothing — speak the protocolKernel API
Change Dirac’s behaviorsrc/hooks/useDirac.ts + src/services/Dirac architecture