Adom TSCI - Tscircuit Board Viewer
Public Made by Adomby adom
Interactive tscircuit preview in a Hydrogen webview — first-class 3D / PCB / Schematic tabs, Components & Nets HUDs, an auto-glow x-ray view, Inspect, Measure, a Walkthrough Demo, and a one-click `exp
| Name | Last updated |
|---|---|
| guides | 1d ago |
| adom-tsci-1.2.0-demo.webm | 1mo ago |
| adom-tsci-1.3.7-tour.webm | 1mo ago |
| adom-tsci-billboard.png | 24d ago |
| adom-tsci-hero-v4.png | 24d ago |
| adom-usbc.md | 1d ago |
| demo-recording.md | 1mo ago |
| demo-v0.4.1-final.webm | 1mo ago |
| export-wiki.md | 1mo ago |
| install.sh | 1d ago |
| LICENSE | 25d ago |
| package.json | 1d ago |
| page.json | 1d ago |
| README.md | 1d ago |
| screenshot-3d.png | 1mo ago |
| screenshot-compare.png | 1mo ago |
| screenshot-components-hud.png | 1mo ago |
| screenshot-hero-3d.png | 1mo ago |
| screenshot-inspect-board.png | 1mo ago |
| screenshot-inspect-chip.png | 1mo ago |
| screenshot-inspect-pad.png | 1mo ago |
| screenshot-pcb.png | 1mo ago |
| screenshot-rerun.png | 1mo ago |
| screenshot-schematic.png | 1mo ago |
| screenshot-walkthrough-contacts-flyover.png | 1mo ago |
| screenshot-walkthrough-fpga.png | 1mo ago |
| screenshot-walkthrough-silkscreen.png | 1mo ago |
| shot-01-iso.png | 1mo ago |
| shot-02-hud.png | 1mo ago |
| shot-03-parts.png | 1mo ago |
| shot-04-lint.png | 1mo ago |
| SKILL.md | 1d ago |
| uninstall.sh | 25d ago |
| VERSION | 1d ago |
| walkthrough-1.3.90-lite.webm | 1mo ago |
Tscircuit Board Viewer (adom-tsci)
Interactive tscircuit preview inside a Hydrogen webview panel. First-class 3D / PCB / Schematic tabs rendered from the tscircuit build output, plus:
- 🔍 Inspect tool (key
I) — hover any feature for a labelled info card: chip refdes + footprint + pin count, pad → net routing ("Connects to MC1.pin1, TP1.pin1 via 2 direct traces"), machine- contact role (mechanical-only vs wired), board stackup + baked- texture resolution, silkscreen text. - 📏 Measure tool (key
M) — Fusion 360-style picking (pad / hole / chip / pin / edge), precision + mm/inches/mils. - 🎬 Walkthrough Demo — narrated tour generated deterministically from
circuit.jsonbyadom-tsci walkthrough-gen(connectors → ICs → grouped passives → nets x-ray), with 3D flyover animations. Connector edges are computed (not hardcoded), long ref lists are capped, and it finishes on the ViewCube Home view with the Nets/x-ray panel turned off. Don't hand-editwalkthrough.json— it auto-regenerates oncircuit.jsondrift. - ⟳ Re-run autorouter — one click touches
lib/index.tsx+ spawnsbunx tsci build --glbs --svgs. --texture-resolution N— re-bakes the board-surface texture (silkscreen + copper pads + annular rings + solder mask) up to 8192×8192 viacircuit-json-to-gltf, cached bycircuit.jsoncontent hash. Essential for readable silkscreen on big boards.- Stale-deps check against
@tscircuit/clion startup. - Secondary tabs:
tsci live(raw RunFrame) and3d compare.
Recent (1.4.x):
- Canonical Adom app-header — one-row
brand · subject · actionswith a hover app-info popover (version / engine / wiki / GitHub), brand fonts (Familjen Grotesk / Satoshi / JetBrains Mono), Adom-teal accent. - Parts inspector lists EVERY component, grouped by kind (
Resistors 92,LEDs 90, …) with collapsible groups — passives are no longer hidden. - Ground plane is 65% transparent and self-heals — the bottom layer / bottom silkscreen show through; a footer readout reports the live transparency so a regression to opaque is caught instantly.
- Panel deep-linking —
#3d/#pcb/#schematic/#parts/#tsci-liveURL hashes select a panel (shareable + AI-drivable). view home— CLI/HTTP preset for the ViewCube Home view.- TTY-gated CLI color so
OK:/ERROR:/Hint:never leak ANSI into pipes.
As of v0.3.0 the 3D tab is fully AI-drivable: every toolbar
button has a CLI subcommand + HTTP endpoint, plus there's a /eval
channel for hot-patching the running JS and a /console forwarder so
Claude can read uncaught errors without clicking anything. No Adom
Viewer service dependency — the Adom 3D viewer library is bundled
into the binary.
As of v0.4.1, adom-tsci start does a pre-flight /proc sweep
for stale bun tsci dev processes and cleans them up before spawning,
plus holds an atomic PID lock at /tmp/adom-tsci-<port>.pid. No more
orphan tsci devs compounding across crashed restarts.

Credit to Ray
This app is an onboarding layer over Ray's authoritative tscircuit
workflow guide at
~/.claude/skills/adom/guides/adom-tscircuit-skill.md. Everything
it does with tscircuit — the <Molecule> component,
MachineContactMedium placement rules, the sizing grid, the DRC
notes, the bunx tsci build --glbs --svgs flags, the project
skeleton — traces back to Ray's guide. Go read it for connector
families, molecule generators, review servers, and DRC tooling.
adom-tsci just makes the "show me what I'm building" step trivial.
The UI
Primary tabs:
- 3D (default). Full-bleed canvas rendered by the Adom 3D
Viewer (Babylon-based engine, bundled into the binary — no AV).
Contact shadow + 65%-transparent ground plane (the board's
bottom layer / silkscreen show through; a footer readout reports
the live transparency). The ViewCube (top-right) handles Home /
Fit / view presets; a floating draggable toolbar over the canvas
carries ▭ ground, ⎚ wireframe, axes, 📏 measure, inspect, and the
walkthrough. Floating component panel lists every chip / passive /
testpoint / contact from
circuit.json— click a row to hide that component and see the traces routed under it. - PCB. Inline
dist/lib/index/pcb.svgin a panzoom container. - Schematic. Inline
dist/lib/index/schematic.svg, same panzoom. - Parts. Inspector listing every component grouped by kind (Connectors / LEDs / Resistors / Capacitors / Machine pins …) — click any to verify its footprint ↔ 3D-body alignment.



Secondary tab:
- tsci live. The raw tscircuit RunFrame through a slingshot proxy. Escape hatch for features upstream tscircuit ships that we haven't wrapped yet. Dimmed 0.78 because RunFrame is hardcoded-light-theme.
The Re-run autorouter button
Top-right of the header, right next to the GLB timestamp pill.

Click it to:
- Touch
lib/index.tsxvia the slingshot →tsci devfile server. Fires aFILE_UPDATEDevent, RunFrame's in-memory view refreshes. - Spawn
bunx tsci build lib/index.tsx --glbs --svgsin the background. Regenerates the on-disk3d.glb,pcb.svg, andschematic.svg, which the first-class tabs poll for (/glb/metaevery 3 s). Within ~30 s the 3D tab re-renders with the new layout and the PCB + Schematic tabs re-fetch on next click. - Shift-click for a clean re-run — also deletes
manual-edits.jsonfirst so any interactive trace edits made in RunFrame's PCB editor are discarded.
Same from the CLI: adom-tsci rerun or adom-tsci rerun --clean.
Stale-deps check
adom-tsci start fires a background query against
https://registry.npmjs.org/@tscircuit/cli/latest on launch and
compares to the version in
<project>/node_modules/@tscircuit/cli/package.json. If you're
behind, you get one HINT: line:
HINT: @tscircuit/cli is out of date (installed 0.1.1226, latest 0.1.1234).
Run `adom-tsci upgrade` to refresh.
Non-fatal, 3-second timeout, never blocks startup. tscircuit does daily releases; this nudges you when you drift behind.
adom-tsci upgrade [project-dir] shells out to bun update --latest
in the target project.
Quick start
# Install (one-time)
adom-wiki pkg install adom/adom-tsci
# From inside a tscircuit project directory:
adom-tsci start .
# Edit lib/index.tsx, click ⟳ Re-run autorouter in the header,
# watch the 3D / PCB / Schematic tabs re-render.
# When done:
adom-tsci stop
If you don't have a tscircuit project yet, see the adom-tscircuit
skill for the 4-file skeleton.
Demo video
A 4-minute feature tour of everything in 1.2.0 is published at
apps/adom-tsci on the wiki
— 34 scenes with TTS narration, recorded against the RP2040 dev-board
molecule.
The full demo pipeline (scene script, TTS generation, per-scene
recording, mux + concat) lives under demo/ and is
reproducible — see demo/README.md. Run it against
any tscircuit project to re-cut the tour.
Examples
Ready-to-build example molecules live under examples/
— clone, bun install, and adom-tsci start <example-dir> to preview.
examples/SN65HVD230-Molecule/
Small reference molecule: a Texas Instruments SN65HVD230 CAN transceiver
in SOIC-8, wrapped in a 16×16 mm molecule with power + CAN bus broken out
to six MachineContactMedium pins. Includes a 100 nF decoupling cap, the
120 Ω CAN bus termination resistor, and per-pin silkscreen labels.

examples/BME680-Breakout-Molecule/
Environmental-sensor breakout: a Bosch BME680 four-in-one sensor
(temperature, humidity, barometric pressure, and a heated metal-oxide
gas-resistance plate that tracks VOC concentration) in a 3×3 mm LGA-8
package, wrapped in a 24×16 mm molecule. Power + I²C bus + the two
SPI-only pins (SDO, CSB) are broken out on six MachineContactMedium
pins. Internally: 100 nF decoupling on each supply rail (VDD and VDDIO),
10 kΩ pull-ups on SDA and SCL, and a third 10 kΩ from CSB→VDDIO so the
chip boots into I²C mode (address 0x77 by default; tie SDO low at the
host to switch to 0x76 and run two BME680s on one bus). One <testpoint>
per broken-out signal for probing-workcell access, and a bottom-silk ID
card (part number, function, I²C address, supply range, revision).

examples/BHI360-Breakout-Molecule/
Motion-sensor breakout: a Bosch BHI360 6-axis IMU (accelerometer +
gyroscope) with a built-in Fuser2 DSP core that runs orientation-fusion
firmware on-chip, so the host MCU can stay asleep while the sensor
tracks motion. LGA-20 (3×2.5 mm) package, wrapped in a 24×24 mm
molecule. Eight MachineContactMedium pins break out the SPI/I²C
interface (CSB / SCK / SDI / SDO, left edge) and power + interrupt
(INT / VDD / VDDIO / GND, right edge) — tie CSB high at the host to
select I²C, leave it driven for SPI. Internally: 100 nF decoupling on
each supply rail (VDD core + VDDIO I/O), silkscreen section headers
(SPI/I2C / PWR), a bottom-silk ID card, and one 0.8 mm
<testpoint> per broken-out signal for probing-workcell access.
Demonstrates an LGA-20 part on a footprinter that only ships
qfn/son/dfn/bga primitives — qfn20_w4mm_h4mm_p0.5mm is used
as the closest spatial match (QFN pads sit where the LGA pads land
on the bottom of the package).


examples/iCE40HX1K-VQ100-Molecule/
Big FPGA breakout: a Lattice iCE40HX1K in a 14×14 mm TQFP-100 (VQ100)
package, wrapped in a 56×56 mm molecule that breaks out all 100 chip
pins to MachineContactMedium contacts on the matching edge. Each pin
also gets a dedicated <testpoint> for probing-workcell access.
Silkscreen sections group the pins functionally:
SPI (programming), PROG (CRESET/CDONE), IO BANK 0/1/2/3, plus a
NO USB / NO UART / NO SWD reminder — the iCE40 is an FPGA, not an MCU,
so there's no debug port in the ARM sense; you program it through the
SPI pins (pins 67–71) via an iCELink/FT232 adapter and boot from a
downstream SPI flash.


examples/iCE40HX1K-USB-Molecule/
Same iCE40HX1K FPGA, now with USB-C programming built in — an
"easy to use FPGA dev board." Plug a USB-C cable from your host into
the board and load a bitstream with iceprog or fujprog. No external
programmer, no JTAG dongle, no manual pin wiring.
Onboard stack:
- USB-C receptacle with ESD protection (USBLC6-2P6)
- FT2232H — dual-channel USB→SPI/UART bridge. Channel A in MPSSE
mode talks to the iCE40's SPI programming pins (
iceprog-compatible). Channel B is a USB-UART console you can attach to a soft-UART running inside your FPGA bitstream. - W25Q16JV 2 MB SPI boot flash — the FT2232H writes your bitstream here, and the iCE40 reads from it on power-up so the board boots standalone without a host.
- AP7333-33 (3.3 V) and AP2112-1V2 (1.2 V) LDOs from USB 5 V for FPGA VCCIO + VCC core rails
- 12 MHz crystal for the FT2232H, 93LC56B EEPROM for its USB VID/PID
- 32 GPIO + 3 power contacts broken out on the molecule edge
- Programming pass-through — 6 edge contacts on the left side
(
SCK / SS / SO / SI / CRESET / CDONE, marked with a→ VQ100 PROGsilkscreen callout) that carry the FT2232H's SPI bus out to mate with a downstreamiCE40HX1K-VQ100-Molecule. Dock that molecule here and a singleiceproginvocation reaches the bare FPGA through this board's onboard USB bridge. - 16 test points on the critical nets (VBUS, 3V3, 1V2, GND,
USB D+/- on both sides of the ESD chip, the SPI programming bus,
CRESET/CDONE, UART TX/RX) as SMT copper pads for a probing workcell's
pogo pins —
footprintVariant="pad", 1 mm diameter, top layer


Architecture
+---------------------------+ +---------------------------+
| Hydrogen webview tab | | adom-tsci (Rust) |
| /proxy/8850/ |<------>| tiny_http on 8850 |
| | | |
| +----------+ | | / shell.html
| | 3D |<------------+------->| /glb file stream
| +----------+ | | /pcb.svg file stream
| | PCB | | | /schematic.svg file stream
| +----------+ | | |
| | Schematic| | | /runframe/ slingshot
| +----------+ | | /runframe/api/* (proxy)
| | | /runframe/standalone.min.js
| +----------+ | | |
| | tsci live|<------------+------->| /runframe/… slingshot
| +----------+ | | |
| | | /basic-3d.html (legacy)
| | | /js/adom-3d-viewer.min.js
| | | /js/environmentSpecular.env
| | | |
| | | /console /eval /eval/* (AI bridges)
| | | /api/set-view /api/set-camera
| | | /api/toggle /api/toggle-component
| | | /api/components /api/tour
| | | /rerun /reload /shutdown /health
| ⟳ Re-run autorouter -----+------->| |
+---------------------------+ +---------------------------+
|
v
+--------------------+
| bun tsci dev |
| -p 3040 |
| (process group) |
+--------------------+
The slingshot fix (why this app exists)
tsci dev emits a hardcoded absolute URL in its HTML shell:
window.TSCIRCUIT_FILESERVER_API_BASE_URL = "http://127.0.0.1:3040/api";
Inside a Hydrogen webview iframe, 127.0.0.1 is the user's machine,
not the container — so every fetch fails and RunFrame hangs at
loading... forever. adom-tsci's slingshot rewrites that line (and
the absolute /standalone.min.js script tag) to relative paths,
then transparently proxies /runframe/api/* to tsci dev on port 3040.
v0.2 note: the v0.1 proxy handler had a bug where route-match
query-string stripping also dropped the query string on forward,
breaking files/get?file_path=.... v0.2 ships a full method/body/
query-aware proxy handler. If you're upgrading from v0.1, this is
why your tabs suddenly work.
tsci dev uses HTTP polling (/api/events/list?since=<id>), no
WebSockets, so the slingshot is a plain HTTP forwarder.
CLI commands
See SKILL.md for the full reference. Summary:
| Command | Purpose |
|---|---|
start <dir> |
Spawn tsci dev, start slingshot, open webview tab |
stop |
Clean shutdown (kills whole tsci process group) |
status [--json] |
Query running instance state |
open |
Re-add or navigate webview tab |
reload |
Force first-class tabs to re-poll build outputs |
rerun [--clean] [--fast] |
Re-run the autorouter (touches .tsx + spawns build) |
upgrade [dir] |
bun update --latest in target project |
health |
Probe tsci_reachable |
install |
Drop SKILL.md into ~/.claude/skills/adom-tsci/ |
| AI-drive the 3D viewer | |
view <preset> |
home (ViewCube Home)/front/back/left/right/top/bottom/iso |
camera [--alpha A] [--beta B] [--radius R] |
Raw camera position |
tour start | stop |
Cinematic slow-orbit |
toggle <flag> |
Flip ground/wireframe/axes |
toggle-component <NAME> [--hide | --show] |
Show/hide a component (e.g. U1 to see traces) |
list-chips |
List components the UI discovered in the current GLB |
eval "<js>" |
Run JS inside the webview, print the result |
console [--follow] |
Tail the forwarded JS console (logs + uncaught errors) |
HTTP API
Every state-mutating CLI command is a thin wrapper over an HTTP
endpoint. AI agents and shell scripts can curl them directly:
curl http://127.0.0.1:8850/health
curl http://127.0.0.1:8850/glb/meta
curl -X POST http://127.0.0.1:8850/rerun
curl -X POST "http://127.0.0.1:8850/rerun?clean=1"
curl -X POST http://127.0.0.1:8850/shutdown
See SKILL.md for the full reference.
Development
git clone https://github.com/adom-inc/adom-tsci
cd adom-tsci
cargo build --release
cp target/release/adom-tsci ~/.local/bin/
adom-tsci install
Rust 1.70+, standard cargo toolchain. Unit tests cover the
slingshot HTML rewrite (the load-bearing regex):
cargo test
Known v0.3 limitations
- Component mapping coverage is partial. The UI groups GLB
meshes by nearest pcb_component centroid; some multi-mesh
components (especially SOIC/SOT bodies with many primitives) can
end up split across neighbouring names or fall into the
Boardcatch-all. Kind-aware tolerances (chip=10mm, testpoint=1.2mm, contact=2mm, …) get most of the obvious ones right; edge cases tracked for v0.4. - The tsci live tab is dimmed (
filter: brightness(0.78)) because tscircuit's RunFrame is hardcoded light-theme. When they ship a dark mode, the filter comes out. - Re-run autorouter rebuilds the whole circuit, not just the autorouter. tscircuit doesn't expose a standalone "run just the autorouter" entry point — the only way to refresh route layouts is to re-evaluate the circuit, which runs the whole pipeline. On a single-chip molecule this takes ~30 seconds.
- GLB is bundled into the binary (the
adom-3d-viewer.min.jslibrary is 13 MB,environmentSpecular.envis ~270 KB), pushing the release binary to ~18 MB. Trade-off: self-contained, zero runtime dependencies, offline-friendly.
Design document
The original design plan lives at
docs/design/valiant-herding-dove.md,
preserved from the v0.1 planning session. Every non-obvious choice
(Rust over Bun, three.js in the generic pane, port 8850, the
"don't touch Ray's guide" boundary, why the slingshot uses a regex
rewrite) is documented there. v0.2 adds the first-class tabs,
rerun button, upgrade check, and the renamed binary on top of that
foundation — see the commit history for the v0.1 → v0.2 evolution.
Acknowledgements
- Ray — for the tscircuit workflow guide this app exists to support.
- tscircuit — for the DSL and the RunFrame bundle.
- The Adom platform team — for the webview panel API,
Basic3dView,
serve_glb, the shotlog service, the brand guide (icons must be monochrome#e6edf3— this app's favicon follows that rule), and thehydrogen-tab-iconsskill that documents how tab icons actually work.
License
MIT. See LICENSE.