Skip to content

Why pcbjs ​

A board is mostly repetition, arithmetic and rules: a footprint is a grid of pads, a placement is a coordinate worked out from another one, a net is a name that must be spelled the same in two places, and a fab says what it can build. Code is good at all of that. pcbjs makes the code the design: a board is a TypeScript module whose default export is a JSX tree, and one compile turns it into checked copper, the files a fab needs and a viewer.

What you get ​

  • Typed schematics. Nets and parts are values. A misspelled net or pin is a type error in the editor, not a new net with one pad found at review.
  • One compile. Placement, routing, pours, connectivity, DRC and ERC run every time, in seconds for the boards in the examples. There is no separate step to forget.
  • Findings that point at code. Each one names the rule, the position, the parts and the source line to change, in the terminal, the JSON report, the viewer and the editor.
  • Ordinary software tooling. Diffs are readable, review happens in pull requests, a part is a function, a channel is a .map, and boards share footprints and pinouts as ordinary modules.
  • The fab set. Gerber X2, Excellon, a job file, BOM, placement and a README-fab that says whether the board is orderable, for the preset of the fab you order from.

Compared with scripted KiCad ​

A common way to get some of this today is a Python script that writes or edits a .kicad_pcb, through KiCad's pcbnew module or by emitting its s-expressions, followed by work in KiCad's GUI and kicad-cli for DRC and the fab files. pcbjs import board turns such a board into a pcbjs project, and its tests hold the result to KiCad's own fab set: on two test boards, one with every library pad shape on both sides and one with slotted pads, an arc track, custom rules and a schematic, copper, mask, paste and outline match kicad-cli's Gerbers by bounding box to 2 µm and the drill files hole for hole.

Scripted KiCadpcbjs
Source of truththe script and the .kicad_pcb it writes, which drift once someone edits the board in the GUIthe TSX module; every output is generated from it
Netsstrings, checked when the board is opened or DRC runstyped values, checked by TypeScript as you type and at connect
Routingby hand in the GUI, or tracks computed in the scriptmanual tracks, automatic legs, pairs and length tuning in one route() chain, cached and lockable
ChecksKiCad's DRC, run in the GUI or with kicad-cli as a separate stepDRC and ERC in every compile, findings tied to source lines
Feedback looprun the script, reload the board, looksave, and the viewer recompiles in place
Schematica full schematic editor with symbols and sheetsa netlist in code, no drawn schematic
Interactive workpush and shove routing, a mature GUInone: the code is the interface, the viewer is for looking
Maturitydecades of production usea proof of concept

KiCad is the better tool for a board that needs a drawn schematic, interactive routing or a team used to its GUI. pcbjs is for boards that are generated, parametric or repetitive, for designs that live in a code review, and for an agent that writes the board as code and reads the findings. Coming from KiCad, Coming from KiCad says what carries over one to one, and Importing from KiCad turns a .kicad_pcb or a footprint into pcbjs code.

What it is not, yet ​

pcbjs is pre 0.1. There is no drawn schematic, no interactive or push and shove routing, and no KiCad export. Length tuning adds serpentines after routing and never reroutes to make room. Development keeps the full list of what is not there yet, and Design explains why the compiler is built the way it is.

MIT licensed. A proof of concept, pre 0.1.