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 on OpenCascade | shipped |
| 2.6 | Multi-board projects: named boards, firmware, and bodies | 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
boards:
main:
entry: hardware/index.tsx
out_dir: dist
port: 3020
mcu: stm32g431
firmware:
app:
board: main
path: firmware
framework: embassy
pins_rs: firmware/src/pins.rs
build_cmd: cargo build
One project, three worlds
A Fusible project links circuit boards, firmware, and physical bodies. Each section holds named entries, and names are unique across the three, so any command takes one as its target:
name: rover
boards:
main:
sensor:
firmware:
main-fw:
sensor-fw:
bodies:
case: # drawn in FreeCAD, Fusion, Onshape...
knob: # code-CAD
lid: # Fusible owns and regenerates it
fusible checkchecks every board and reports all violations together.fusible check sensorchecks one.fusible build sensor-fwchecks thesensorboard, writes its pin bindings, then builds that firmware.fusible export main --preset fabwrites intodist/main/fab/. With several boards,exportanddevneed a board name.- A firmware or generated body must name its board when the project has more than one.
- The single-board form (
hardware:,mcu: { chip }, onefirmware:,mechanical:) still loads. It becomes a board namedmain, a firmware namedfirmware, and a generated body named after the project, which keeps writingdist/mechanical/<project>.<format>.
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. BODIEStab showing the generated base and lid, with lid and explode toggles. The 3D view has anENCLOSUREtoggle that draws the shell translucent around the board. The studio builds the model on demand from the first generated body infusible.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 boards, lints electrical rules, generates typed firmware pin bindings (pins.rs), and compiles firmware only if every board keeps the fuse 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. Physical bodies (body)
Builds the bodies of the project. A body is either authored or generated:
- Authored (
source:): a file you made in any CAD tool. Fusible checks that it exists and never overwrites it. Withbuild:, Fusible first runs that command from the manifest directory, for code-CAD tools such as build123d, CadQuery, or OpenSCAD. - Generated (
generate: enclosure): a two-part enclosure (base + lid) around the board outline in Circuit JSON. Fusible owns the file and regenerates it on every run. Generation is fuse-gated likeexport.
A board without any body gets a default enclosure, so fusible body works without a bodies: section. mechanical, case, and housing remain aliases of body.
Enclosure details:
- 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 body settings in
fusible.yml, which override defaults. - Requires
bun. The first run installsocct-wasminto~/.cache/fusible/. IGES is not supported. fusible devpreviews the first generated body in itsBODIEStab 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