wokwi-autoroute
v1.0.0
Published
Auto-place and auto-route Wokwi diagrams from a simple parts+wires spec — no manual wire dragging.
Maintainers
Readme
⚡ wokwi-autoroute
Auto-place and auto-route Wokwi diagrams — no manual wire-dragging
npmjs.com/package/wokwi-autoroute ·
The problem
Wokwi has no auto-router. Wires are dragged by hand or steered with a manual
route mini-language (v10, h5, *), and on any real board they pile into spaghetti that overlaps
pins and cuts across components. Tidying it up by hand is slow, fiddly work — and you do it again on
every project.
What it does
Give it the parts and the connections — or point it at a messy diagram.json — and it returns a clean,
placed, fully-routed diagram.
spec (parts + wires) → auto-place → auto-route on the grid → diagram.jsonEvery wire sits on Wokwi's 0.1-inch grid, enters each pin straight on, never crosses a component, and no two different nets ever share a lane.
One command. No wire-dragging.
Use it
No install — run it straight from npm:
npx wokwi-autoroute board.json -wboard.json is either a short spec (below) or an existing Wokwi diagram.json — point it at a
tangled diagram and it reads the parts and connections back, then re-places and re-routes them.
npx wokwi-autoroute board.json -w # overwrite the file in place
npx wokwi-autoroute board.json -o out.json # write to a new file
npx wokwi-autoroute board.json # print to stdout
npx wokwi-autoroute board.json --fast # skip the placement search (instant)Open the result in Wokwi — it's placed and routed, ready to simulate.
The spec
A small JSON file: which board, which parts, and what connects to what.
{
"board": "esp",
"parts": {
"esp": { "type": "wokwi-esp32-devkit-v1" },
"dht": { "type": "wokwi-dht22" },
"led": { "type": "wokwi-led", "attrs": { "color": "red" } }
},
"wires": [
["dht:SDA", "esp:D15", "green"],
["dht:VCC", "esp:3V3", "red"],
["dht:GND", "esp:GND", "black"],
["led:A", "esp:D26", "orange"],
["led:C", "esp:GND", "black"]
]
}board— the part pinned at the origin; everything else is placed around it.parts—id → { type, attrs? }.typeis any @wokwi/elements part; its geometry is read automatically.wires—["fromId:PIN", "toId:PIN", "color"?]. A pin can be a net likeGND— the nearest instance (GND.1/GND.2) is picked per wire.
Same pipeline, programmatically:
import { build } from "wokwi-autoroute";
const { diagram } = await build(spec);Before / after
[IMG — before: the same board wired by hand, wires overlapping and crossing parts] [IMG — after: auto-routed, every wire on the grid, nothing overlapping]
Roadmap
- [x] Auto-place each module on the board side its pins face
- [x] Grid A* maze router — perpendicular pin exits, shortest clean paths
- [x] Every wire on Wokwi's 0.1-inch (9.6px) grid
- [x] Overlap-free by construction — different nets never share a lane
- [x] Clean same-pin merges — shared grounds/power ride one trunk into the pin
- [x] Placement optimizer that scores layouts by wire quality
- [x] Read back and re-route an existing
diagram.json - [ ] Part rotation (kept upright for now)
- [ ] More parts in the geometry DB
How it's built
Routing is a grid A* maze router. The search runs on Wokwi's absolute 9.6px grid, so every wire is grid-aligned by construction. Pins sit slightly off that grid, so each one is bridged to the nearest grid node by a forced perpendicular stub — that's what makes a wire leave a pin straight instead of sideways.
Every grid edge carries a net tag: a different net can't reuse an edge (so two nets never overlap on a
lane) but may cross it, and same-net edges are cheap — so wires to a shared pin merge onto one trunk and
ride it in together. A keepout ring around each part keeps wires from hugging components. Part geometry —
size, pin positions, and which edge each pin is on — is read straight from @wokwi/elements; nothing is
hardcoded.
A placement optimizer wraps the router: it nudges each module and keeps the layout that scores best on a
road metric (turns + length on the merged wire roads), with part overlaps and component crossings as hard
gates. The CLI verifies the result on every run and prints ✓ 0 wire overlaps — it never finishes
silently while two nets share a road.
Stack
Node.js · @wokwi/elements · a custom grid A* router
Try it → npx wokwi-autoroute board.json -w
Because dragging wires by hand is nobody's idea of fun.
