Skip to content

For agents ​

pcbjs is built to be driven by a coding agent as much as by a person: one command checks a board, every finding names the source line to change, and every topic file prints in the terminal. This page is the For agents section of the README, which an agent reads first. The package @pcbjs/skills carries the same guidance as agent skills.

Read this section, then pcbjs docs <topic> for the one topic you need, or the same page under https://pcbjs.dev/docs/. Do not read the whole docs folder.

Mental model ​

  • Schematic: nets() gives Net values; a footprint factory with a value gives a Part; .connect(...) binds pins to nets and throws at the call when a pin is wrong.
  • Parts are values: put them in arrays and objects, make them in .map and plain functions, and name a group of them with group('P1', { J, SW }) so findings say U8 (P3/SW).
  • Layout: a part is placed as a JSX element, <R1 at="9 7.5" />. A part bound to a variable named like a ref, const R1 = …, is R1; other parts are numbered by declaration order.
  • Routes: route(a) and a chain from a pin handle, .H(x), .via('B.Cu'), ending at .Z(b) for a straight track or .X(b) for an automatic leg, which the autorouter lays after everything else is placed. route(a, b, path) with a path string is the same route.
  • Build: one compile gives the board model, DRC, ERC, the fab set and the site. pcbjs check is the build without files; its findings carry position, refs and the source line to change, and pcbjs inspect prints where parts, pads and nets ended up, in absolute mm.

Commands ​

sh
pcbjs check                             # the loop: the entries in pcb.config.ts; compile, route, DRC, ERC; exit 1 on errors
pcbjs check --json .pcbjs/r.json        # every finding with a stable id, for scripts
pcbjs check --watch                     # recompile on save, print new and fixed findings
pcbjs inspect                           # every footprint: ref, path, value, at, rot, side, source
pcbjs inspect U1                        # one part's pads: number, name, net, centre, size, layers
pcbjs inspect GND                       # one net: pads, vias, track widths, failed routes; also REF.PAD
pcbjs inspect U1 GND --lengths DATA     # several answers from one compile; route lengths of a net, pair or group
pcbjs inspect coin.pcb.tsx U1           # with several entries, name the board's entry first
pcbjs build -q                          # fab set and site, summary lines only
pcbjs dev -p 0                          # live viewer on a free port, URL in the first lines
pcbjs dev --workspace .                 # one server for every project below, each loaded on first use
pcbjs shot --select U1 --select J1      # PNGs framed on each part, in .pcbjs/shots; --layer repeats too
pcbjs docs routing                      # one topic; pcbjs docs lists them
pcbjs docs --grep 'neck|escape'         # every doc line that matches, a word or a regex

Reading pcbjs check ​

A board whose LED route is walled off by a keepout:

Probe  pcb.tsx  3 footprints, 6 pads, 1 track, 0 vias, 0 zones, 3 nets  DRC 3 errors, 0 warnings, 2 unconnected  ERC ok  FAIL  254 ms: route 45 ms, zones 1 ms, connectivity 1 ms, drc 4 ms, erc 8 ms
  routing 1 leg, 0 routed, 1 failed, 0 cached, 0 locked, 0 ripped, 0 rounds
  DRC route-failed: 1 error
    error    route-failed  F.Cu  at (12.00, 7.50)  R1, D1, J1  route:2  pcb.tsx:17:6: cannot route net LED from (9.825, 7.5) on F.Cu to (14.175, 7.5) on F.Cu, layers F.Cu, B.Cu: no path within maxDetour: every way is longer than 14.35 mm, for 4.35 mm between its ends; blocked by the keepout (pcb.tsx:15:6) on F.Cu, B.Cu; nearest obstacles: pad R1.1 (VCC), pad D1.1 (GND), track (VCC) (pcb.tsx:16:27), pad J1.2 (VCC), pad J1.1 (GND)
  DRC unconnected: 2 errors
    error    unconnected  at (9.41, 6.23)  J1, D1  pcb.tsx:13:5: net GND is not fully connected, from J1.1 at (3.00, 4.96) to D1.1 at (15.83, 7.50)
    error    unconnected  LED: net LED is not fully connected: route route:2 failed, see route-failed
FAIL  DRC 3 errors, 0 warnings, 2 unconnected  ERC 0 errors, 0 warnings

The first line is one board: name, entry, counts, DRC and ERC totals, FAIL when not orderable, compile time and phase times. The routing line counts the autorouter legs: routed, failed, reused from the cache, kept by locks, then the legs negotiation took off the board and its rounds. Then the findings, grouped by rule, causes first: route-failed, short, clearance, the rest, unconnected last. A net whose route failed folds into one unconnected line that points at it; --verbose prints every finding unfolded. The last line is the total over every board; exit code 0 means every board is orderable. Take the route-failed line field by field:

FieldHereMeaning
severityerrorerror blocks ordering, warning does not
ruleroute-failedthe DRC rule; ERC rules print as ERC <rule>; pcbjs docs --grep <rule> explains it
layerF.Cuwhen the finding has one
positionat (12.00, 7.50)board mm, x right, y down
refsR1, D1, J1parts involved; inside a circuit R4 (CH2/R)
routeroute:2the route it concerns, as pcbjs inspect --lengths lists it
sourcepcb.tsx:17:6the line to edit: the route call, the part placement or the item; a route made in a helper reads pcb.tsx:40:5 via lib/fan.tsx:12:5, the call site first
messageafter : measured and required values, or for routes the ends, layers tried, a keepout that walls the leg off and the nearest obstacles

Where files land ​

PathWhat
.pcbjs/fab/<board>/Gerbers, drills, bom.csv, cpl.csv, <board>.pcb.svg, README-fab.txt, the zip
.pcbjs/dist/the static site; boards/<board>.json is the full model, large
.pcbjs/routes/<board>.jsoncached and locked routes
.pcbjs/dev.jsonport, pid and route of a running dev server
STALE in a fab dirthe last compile of that entry failed; the files are old

Rules of thumb ​

  • Run pcbjs check, not build, while iterating, --json <file> when a script needs the findings, and pcbjs inspect for coordinates. Never read board.json or compute rotated pad positions by hand.
  • Declare defineFootprint pins inline or as const, or pin names lose their types.
  • Every pad must match a pin by name or number, or be marked nc: <pad nc /> or the footprint's nc list.
  • A pin with several pads routes to the pad nearest the other end. Use the pad handle J1['B4'] to choose, J1.pad('B4') when the pad id is also a pin key.
  • Use keepout() for areas copper must avoid. The router's avoid is only a cost.
  • A route-failed finding names the nearest obstacles. Raise the route's priority, add an X x y waypoint, or allow more layers. Call .lock() on routes you are happy with, so later edits cannot move them.
  • With variants(), targets share one routing under the strictest rules; routeSeparately: true opts one out.
  • Route a differential pair with array ends, route([J1.DP, J1.DN]).X([U1.DP, U1.DN]).impedance(90); the path is its centre line.
  • .length(mm) tunes a route to a target and .match('DATA') tunes a group to its longest; pcbjs inspect <entry> --lengths shows the result.
  • A KiCad footprint is kicadFootprint('Package_SO:SOIC-8_3.9x4.9mm_P1.27mm') in code or pcbjs import footprint <Lib:Name> as a file to edit; a KiCad board starts as pcbjs import board <file.kicad_pcb>, then pcbjs check --fab.
  • When a part is not in the stdlib, take its STEP model from KiCad's library, pcbjs model add <url> --ref J1 --write, or from LCSC's EasyEDA library, pcbjs model add --ref J1 --write for a part with an MPN:LCSC number; pcbjs model check flags misplaced models.

Topics ​

TopicWhat it covers
quickstartinstall, project files, config, the loop
board<PCB> props, units, coordinates, layers, stackup, defaults
schematicnets, parts, connect, pin and pad handles, nc, defineFootprint, typing
circuitscircuits, ports, instance names, layouts
schematic-graphicthe schematic drawing: <Schematic>, symbols, wires, labels, automatic wiring, sch-* findings
sourcingMPN keys, source(), sourcing tags, BOM resolution
layoutelements, pads, pour, via, keepout, shapes, text
pourspour fill, thermal reliefs, islands, stitch() stitching vias
routingroute ends, path grammar, builder methods, teardrops, parameters, net classes
autorouterlayers, vias, order and rip up, failures, keepouts, cache and lock, variants
pairs, lengthdifferential pairs: array ends, centre line, gap, impedance, via pairs, pair DRC; length targets, match groups and meanders
rulesrule values, overrides per pad, part and net, fab rule sets
findingsevery DRC and ERC rule with its severity, and what makes a board orderable
fab, fab-setpresets, bindPCB, variants; every file of the fab set, README-fab, BOM, the Gerber self check
cli, inspectevery command and flag, output formats, JSON report, exit codes; every pcbjs inspect query and its output
viewerthe 2D viewer, panels, multi-board sites
editor, highlightsource links, repository links, VS Code extension, IDE mode, drafts; source ranges and the token under the cursor
3d, modelsthe 3D view and part models; pcbjs model add, align and check, where to find model files and their licences
referencesanother entry's board as a mechanical reference: mate, stack, its two DRC rules, caching, cycles
skillsthe agent skills of @pcbjs/skills: pcbjs skills install, what each skill covers, writing one
stdlibevery footprint family with pins and frame, footprint helpers
kicad, importcoming from KiCad: frame, back side, refs, text, Gerber differences; pcbjs import footprint and board, kicadFootprint(), the refine steps
workspace, stackup-and-rules, fonts, ide-bridge, design, developmentthe workspace dev server, background, the editor protocol, rationale, repository layout and limits

Each is docs/<topic>.md here, pcbjs docs <topic> anywhere and https://pcbjs.dev/docs/ on the web.

MIT licensed. A proof of concept, pre 0.1.