pcb is a command-line tool for building printed circuit boards from Zener files. Zener looks familiar if you have used Python or Starlark, but it is a PCB-specific language with built-ins for nets, power rails, modules, components, board setup, and electrical checks.

The useful mental model is simple: write a .zen design, let pcb validate it, generate KiCad layout files, then use KiCad or kicad-cli to export visuals and manufacturing artifacts.

What is pcb?

pcb is maintained by Diode Computers, Inc. and published as open source on GitHub .

It uses Zener to describe PCB schematics and adds automation around KiCad. The repository is a Rust workspace, but day-to-day usage is through the pcb command.

License: MIT ❤️

What It Produces

The first output is not an image. pcb build behaves more like a compiler:

✓ blinky.zen (2 components)

From there, other commands produce richer artifacts:

  • pcb bom prints a bill of materials.
  • pcb fmt checks or formats .zen files.
  • pcb layout generates a KiCad project and .kicad_pcb board.
  • kicad-cli can export SVG, PDF, Gerbers, STEP, stats, and other board artifacts.

For the tiny blinky test, the exported board image is available here:

Open the generated SVG

The generated KiCad board is also included:

Open the generated KiCad board

Tech Overview

The project has two important binaries:

  • pcb: a small shim that selects and installs the right toolchain.
  • pcbc: the actual command-line implementation.

The source tree includes crates for the Zener runtime, core PCB language concepts, KiCad integration, layout generation, formatting, simulation, Gerber handling, and IPC-2581 tooling.

That split matters because the installer can place a small pcb binary on your PATH, while project-specific toolchains are cached separately.

Installing KiCad 10 on Ubuntu

The first local layout attempt failed because this machine did not have KiCad’s Python module:

ModuleNotFoundError: No module named 'pcbnew'
Error: Python script execution failed

On this Zorin OS 18.1 machine, the stock Ubuntu noble package offered KiCad 7.0.11, but this project expects KiCad 10.x. The working path was the KiCad 10 PPA:

sudo add-apt-repository ppa:kicad/kicad-10.0-releases
sudo apt update
sudo apt install kicad

Then verify the CLI and Python binding:

kicad-cli version
python3 -c "import pcbnew; print(pcbnew.Version())"

Observed locally:

10.0.3
10.0.3

Importing pcbnew printed a few KiCad assertion warnings on this install, but it did not block layout generation.

KiCad UI

Trying pcb with the Blinky Example

I installed the pcb shim into a temporary folder so it would not change the normal shell setup:

mkdir -p /tmp/pcb-test-install /tmp/pcb-test-work
PCB_INSTALL_DIR=/tmp/pcb-test-install /tmp/foss-post-repos/pcb/install.sh

The shim went to /tmp/pcb-test-install/pcb, while the downloaded pcbc 0.3.90 toolchain was cached under:

~/.local/share/pcb/toolchains/0.3.90/x86_64-unknown-linux-gnu/pcbc

Then I copied the example design:

cp /tmp/foss-post-repos/pcb/examples/blinky.zen /tmp/pcb-test-work/blinky.zen
cp /tmp/foss-post-repos/pcb/examples/pcb.toml /tmp/pcb-test-work/pcb.toml
cd /tmp/pcb-test-work

Build validation:

/tmp/pcb-test-install/pcb build blinky.zen

Output:

✓ blinky.zen (2 components)

BOM generation:

/tmp/pcb-test-install/pcb bom blinky.zen

The example resolved one LED and one resistor:

Designator MPN Manufacturer Package
D1 VLMS1500-GS08 Vishay Semiconductor Opto Division 0402
R1 ERJ-2RKF1001X Panasonic Electronic Components 0402

Generating KiCad Files

Once KiCad 10 was available, layout generation worked:

/tmp/pcb-test-install/pcb layout blinky.zen

Output:

✓ blinky.zen (/tmp/pcb-test-work/layout/blinky/layout.kicad_pcb)

The generated files copied into this site are:

Exporting SVG and Gerbers

KiCad’s CLI can export from the generated .kicad_pcb file:

kicad-cli pcb export svg \
  --mode-single \
  --page-size-mode 2 \
  --layers F.Cu,F.Silkscreen,Edge.Cuts \
  --output /tmp/pcb-test-work/exports/blinky-front.svg \
  /tmp/pcb-test-work/layout/blinky/layout.kicad_pcb

Gerber export:

kicad-cli pcb export gerbers \
  --layers F.Cu,B.Cu,F.Silkscreen,Edge.Cuts \
  --output /tmp/pcb-test-work/exports/gerbers \
  /tmp/pcb-test-work/layout/blinky/layout.kicad_pcb

Generated Gerber files:

The board stats report two front-side SMD components and four SMD pads. This simple example does not define a board outline, so width, height, and area are empty.

Zener Is Python-Like, Not Python

One useful example is typed_nets.zen, which prints net type and casting behavior when run through pcb build.

With pcb:

=== Net Type Casting ===
Cast Ground to Power: foobar
  name: foobar
  type: Power

✓ typed_nets.zen (0 components)

With python3 typed_nets.zen, it fails:

NameError: name 'builtin' is not defined

That is expected. Zener uses familiar syntax, but the runtime is provided by pcb, not CPython.

How It Differs from PySpice

If you searched for pyscipe, you probably meant PySpice: a Python package for working with SPICE simulators from Python.

PySpice sits on the simulation side of the electronics workflow. It gives Python code a way to define circuits, drive Ngspice or Xyce, run analyses, and inspect the resulting voltages, currents, sweeps, and waveforms.

pcb sits on the board-building side. It is not primarily a numerical simulation wrapper. It lets you describe a PCB design in Zener, validate the design, generate a BOM, create KiCad project files, and export layout or manufacturing artifacts.

The tools can complement each other. A practical workflow could use PySpice to explore circuit behavior first, then use pcb to turn the chosen design into a repeatable board workflow.

Useful references:

Conclusion

The test was useful because it showed the complete path from text to board artifact:

Zener .zen
-> pcb build
-> pcb bom
-> pcb layout
-> kicad-cli export svg / gerbers / stats

The current rough edge is setup: KiCad 10 and the pcbnew Python module must be available for layout generation. Once that dependency was installed, the flow worked cleanly for the blinky example.

FAQ