Fusible
The fuse for your firmware. An electronic linter and tscircuit project manager in Rust: it reads the Circuit JSON generated by tscircuit, checks the electrical and physical rules of the board, and when a rule fails, the fuse blows: the process exits with an error and firmware code generation never happens.
Fusible unifies hardware and firmware into a single monorepo contract using fusible.yml,
wrapping development servers, dark-theme web previewers, artifact exports, and firmware codegen.

Project status
| Phase | Scope | Status |
|---|---|---|
| 1 (MVP) | CLI, Circuit JSON parser, rules engine, diagnostics | shipped |
| 1.1 | Project manifest (fusible.yml), toolchain detection, package manager |
shipped |
| 2 | Silicon pin-muxing (src/silicon/) for STM32, RP2040, ESP32-S3 |
shipped |
| 2 | Firmware codegen (src/codegen/pins.rs) for Embassy / Cortex-M |
shipped |
| 2.1 | Pure-Rust RS-274X Extended Gerber & Excellon drill generator | shipped |
| 2.2 | Pure-Rust vector documentation exporter (PCB & schematic SVGs) | shipped |
| 2.3 | Native Fusible Studio dev server with dark theme and live SSE reload | shipped |
| 2.4 | Deterministic autorouter and bidirectional KiCad syncer | shipped |
| 2.5 | Fuse-gated 3D enclosure generator (mechanical) on OpenCascade |
shipped |
Prerequisites
For pure Circuit JSON projects, Gerber exports, SVG rendering, and linter checks, Fusible runs with zero external dependencies.
To compile React .tsx circuits or export 3D STEP models, install tscircuit globally or in your workspace:
# Using bun:
# Or using npm:
Inspect toolchain health anytime with fusible doctor (or run fusible doctor --install to provision it).
Installation
Quick start (monorepo)
Initialize a new hardware + firmware project:
This creates a minimal fusible.yml:
name: sensor-node
hardware:
entry: hardware/index.tsx
out_dir: dist
port: 3020
mcu:
chip: stm32g431
firmware:
path: firmware
framework: embassy
pins_rs: firmware/src/pins.rs
build_cmd: cargo build
Commands
1. Electrical linter (check)
Compiling .tsx through tscircuit stops after 120 seconds. Set FUSIBLE_BUILD_TIMEOUT_SECS to change the limit for boards that take longer to route.
Clean circuit (exit code 0):
Circuit validated (fuse intact)
Rule violated (exit code 1):
the fuse blew: 1 electrical violation(s)
[unconnected_net] net "I2C_SDA" has only 1 connection(s) (minimum 2): it is floating
help: every net must connect at least two pads/ports: complete the routing in tscircuit
2. Fusible Studio dev server (dev / view / webview)
Starts the native dark-theme web previewer powered by an embedded Rust HTTP server and live-reload event streamer:
Features:
- Instant startup with zero Node runtime required for Circuit JSON.
- Live-reload streaming via Server-Sent Events (SSE) with 150ms debounced filesystem watching.
- Vitrine brutalist dark UI palette (
#000000,#131313,#353535,#86A881,#A8B365) and embeddedUndefinedmonospace typography. - Interactive pan and zoom vector canvas for multi-layer PCB layout (
01 // PCB LAYOUT) and schematic diagrams (02 // SCHEMATIC). - Interactive Three.js 3D board viewer (
03 // 3D VIEW) rendering substrate, ENIG gold pads, copper vias, traces, and components with OrbitControls and view presets. MECHANICALtab showing the generated base and lid, with lid and explode toggles. The 3D view has aMECHANICALtoggle that draws the shell translucent around the board. The studio builds the model on demand from themechanical:section offusible.ymland rebuilds it when the circuit changes. Needsbun.- Real-time fuse status badge (glowing green when intact, pulsing red on blown fuse).
- Diagnostics inspector showing rule violations, severity, and remediation advice.
- PCB layer visibility toggles (top copper, bottom copper, ENIG pads, silkscreen).
3. Autorouter (route)
Multi-layer A* autorouter on pure Rust spatial R-trees (rstar). Nets route one at a time in a fixed order, and each finished trace becomes an obstacle for the next, so routed nets cannot short:
When routing congestion prevents a trace from completing, the fuse blows (exit code 1) and lists unrouted nets to protect physical fabrication.
4. Bidirectional KiCad syncer (diff and sync)
Bi-directional layout reconciliation between graphical CAD tools (KiCad PCB) and declarative code (tscircuit):
# Compare component placement and report layout drift:
# Synchronize physical moves and rotations back into manual-edits.json:
# Dry run sync without modifying disk:
5. Build (build)
Evaluates the board, lints electrical rules, generates typed firmware pin bindings (pins.rs), and compiles firmware only if the fuse is intact:
6. Fuse-gated deliverables (export)
Exports fabrication-ready Gerbers, KiCad projects, SVGs, 3D models (STEP/GLB), or documentation. All exports are fuse-gated: electrical rules are verified first. If a rule fails, the fuse blows and no artifacts are produced.
# Presets:
# Specific format exports:
# Bypass verification (for debugging/drafts):
7. 3D enclosure (mechanical / case)
Generates a two-part enclosure (base + lid) around the board outline in Circuit JSON. The command is fuse-gated like export.
- The outline comes from
pcb_board(outlinepoints, orwidthxheight). - Each
pcb_holegets a screw boss with a pilot hole, and the board sits on the bosses. - Components that reach the board edge get a wall notch from the board surface up.
- CLI flags override the
mechanical:section offusible.yml, which overrides defaults. - Requires
bun. The first run installsocct-wasminto~/.cache/fusible/. IGES is not supported. fusible devpreviews the same model in itsMECHANICALtab and as a 3D overlay, without the fuse gate.
8. Hardware package management (add, install, search)
Manage tscircuit packages, community footprints, and components without touching npm or tsci directly:
# Search footprints and components in the tscircuit registry:
# Add a community component or registry footprint to hardware/:
# Install all hardware dependencies:
9. Toolchain diagnostics (doctor)
Inspects local toolchain health (bun, node, npm, npx, tsci) and verifies tscircuit runner availability:
Exit codes
The codes are part of the contract, so CI can tell failures apart:
| Code | Meaning |
|---|---|
0 |
Fuse intact: circuit validated / command succeeded |
1 |
Electrical violations: the fuse blew, generation is blocked |
2 |
Tool or usage error (unreadable/malformed input, bad arguments) |
Architecture
src/
├── main.rs # CLI entry point, exit code mapping
├── cli.rs # Clap command definitions
├── assets/ # Embedded dark-theme web dashboard & Undefined font
├── dev/ # Native Fusible Studio dev server (tiny_http, SSE, notify)
├── router/ # Deterministic multi-layer autorouter (rstar, A*)
├── kicad/ # S-expression parser & bidirectional layout drift syncer
├── commands/ # Subcommand execution pipelines (check, dev, route, diff, sync, export, build)
├── config/ # fusible.yml manifest loader and path resolution
├── gerber/ # Pure-Rust RS-274X Gerber and Excellon drill generator
├── svg/ # Pure-Rust vector renderers for PCB layout and schematics
├── silicon/ # Silicon database and alternate function pin multiplexer
├── codegen/ # Typed firmware pin bindings generator (pins.rs)
├── parser/ # Serde Circuit JSON parser and source span tracking
├── linter/ # Fail-closed rules engine and diagnostics
├── netlist/ # Bipartite graph IR of nets, components, ports, and traces
└── tscircuit/ # Runner discovery and external process control
Development