# SKiDL writes KiCad netlists from Python, and ERC() is what keeps you honest

> SKiDL turns a circuit into a Python program that emits a netlist, an XML bill of materials, SVG diagrams or an editable KiCad schematic. Its value is review and reuse, but the ERC check only catches the classes of error it was written to catch, and symbol resolution depends on a KiCad library path you have to set by hand.

**devbisme/skidl** — SKiDL is a library that lets you design electronic circuits using Python.

- Repository: https://github.com/devbisme/skidl
- Website: https://devbisme.github.io/skidl/
- Stars: 1,702 · Forks: 186
- Language: Python
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/devbisme-skidl

## A voltage divider in fifteen lines

The README's first example is the whole argument for the tool. Two resistors and a ground reference, written as Python:

```python
from skidl import *

vin, vout, gnd = Net('VI'), Net('VO'), Net('GND')

r1, r2 = 2 * Part("Device", 'R', dest=TEMPLATE, footprint='Resistor_SMD.pretty:R_0805_2012Metric')
r1.value, r2.value = '1K', '500'

vin & r1 & vout & r2 & gnd

ERC()
generate_netlist(tool=KICAD10)
```

Three syntax decisions carry most of the weight. Parts are declared as templates with a library name, a symbol name, dest=TEMPLATE and a footprint, and `2 * Part(...)` instantiates two of them. Nets are objects you name. The `&` operator is the connection operator, and chaining it reads as a physical wire path rather than as a sequence of assignments.

If that chain is not to your taste, pin-by-pin connections are available in the same file as comments, using `vin += r1[1]` style syntax. Both forms end at the same netlist.

The second example is more telling because it stops pretending circuits are linear. A two-input AND gate built from discrete transistors connects with expressions that name topology directly:

```python
a & r1 & q1["B C"] & r4 & q2["B C"] & a_and_b & r5 & gnd
b & r2 & q1["B"]
q1["C"] & r3 & gnd
vcc += q1["E"], q2["E"], vcct
```

That line is the pitch for anyone who has traced a signal across multi-page schematics. The string indexing into a part, `q1["B C"]`, connects multiple pins of one component to the same net in one place.

## Templates, instantiation and parametric circuits

The template mechanism is what makes SKiDL more than a drawing API. A Part created with dest=TEMPLATE is a specification, not an object in the circuit, and you instantiate from it with a count. The AND gate example instantiates two transistors from one template and five resistors from another:

```python
q = Part("Transistor_BJT", "Q_PNP_CBE", dest=TEMPLATE)
r = Part("Device", "R", dest=TEMPLATE)
q1, q2 = q(2)
r1, r2, r3, r4, r5 = r(5, value="10K")
```

Values are settable at instantiation, which is how the same code produces different circuits. The README extends this into its claim of reusable design: circuit modules published on PyPI and GitHub, and parametric "smart" circuits that adapt to requirements.

There is also a search path rather than only hand-written parts. The README describes smart part libraries where you search parts by function, footprints are assigned automatically, and any KiCad library is reachable. The package registers two console scripts for this, `netlist_to_skidl` to convert existing KiCad designs into SKiDL source and `skidl-part-search` for the part search command line.

That converter is the practical migration route. If a team has years of schematic files in KiCad, you do not have to redraw them to start using the tool.

## Install, then point it at your KiCad symbols

Installation is one command:

```bash
pip install skidl
```

The setup script declares `python_requires=">=3.6"` and pulls in kinet2pcb, simp_sexp, ply, rich, graphviz, deprecation and, on Python 3.11 or later, the `inspire` package. The current version in setup.py is 2.3.0.

The optional but recommended step is telling SKiDL where KiCad keeps its symbol libraries, through one environment variable:

```bash
# Linux/Mac
export KICAD_SYMBOL_DIR="/usr/share/kicad/symbols"

# Windows  
set KICAD_SYMBOL_DIR=C:\Program Files\KiCad\share\kicad\symbols
```

This is the first thing that will bite you. The troubleshooting section names the failure mode precisely: no libraries found, or symbol resolution errors, because the variable is unset or points at the wrong path, and parts simply will not resolve.

The README lists where the path lives depending on how KiCad was installed, which is worth reading because the answer is not the same everywhere. A package manager install on Linux uses /usr/share/kicad/symbols/, a Flatpak install uses /var/lib/flatpak/app/org.kicad.KiCad/current/active/files/share/kicad/symbols/, a Homebrew install on macOS uses /Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/, and a typical Windows install uses C:\Program Files\KiCad\8.0\share\kicad\symbols.

Check the directory exists with `ls` before setting anything, then confirm resolution from Python:

```bash
python -c "from skidl import Part; r = Part('Device', 'R'); print(f'Found: {r.name}')"
```

## ERC catches wiring errors, not design errors

The ERC() call in both examples is the most underrated line in the README. Electrical rules checking is listed among the reasons to choose the tool, with the specific classes named: unconnected pins, drive conflicts and power connection errors.

Those three are exactly what a netlist-level checker can see. Anything requiring judgement, a wrong resistor value, a missing decoupling capacitor, a series termination resistor omitted on a bus, or a part chosen outside its safe operating area, is outside what ERC reports.

The rest of the output story follows from the same split. One description generates netlists, XML for bills of materials, SVG or DOT diagrams, and editable KiCad schematics. The README specifies KiCad 6 through 10 for editable schematic output in one place and KiCad 5 through 10 for support in the troubleshooting section, so treat the wider range as the safe assumption. For existing designs, the `netlist_to_skidl` entry point converts KiCad netlists back into SKiDL source.

Hierarchical design is the other structural feature. Subcircuits nest, and the README states the hierarchy carries through into the generated netlists and schematics, so a block drawn once can be reused at several levels.

## Simulation, classes and the parts you attach rules to

Beyond generation, the README lists two capabilities worth knowing about before you commit.

SPICE integration means you can run simulations directly on a SKiDL circuit rather than exporting to a separate tool, which means the simulation and the netlist cannot drift apart. Simulation support is not something the quick examples show, and the tests directory is where you would look for what it expects.

Part and net classes let you attach design rules, manufacturing requirements and electrical specs to a set of parts or nets rather than to individual components. This is the feature that matters most in production, because the classes can enforce policy at netlist generation time instead of relying on a reviewer to remember. The relationship to ERC is the useful part: classes are how you encode the rules ERC does not check.

The project also uses a standard Python toolchain, which is visible in the repository files rather than the README. The Makefile targets include `test` running `pytest tests` and `test-all` running tox across Python versions, `lint` running flake8 over skidl and tests, and `coverage`. pyproject.toml configures black and isort with line_length=88, and the isort configuration marks pytest and PySpice as third party, which is a hint that the SPICE path is exercised by the test suite.

## Conclusion

SKiDL fits a team that already works in git and wants schematics to survive code review, produce variants from one source, or generate repetitive structures such as LED arrays without drawing them. It does not fit a one-off board drawn once, since the conversion overhead is only worth it when the design iterates. Verify first that KICAD_SYMBOL_DIR points at real symbol libraries for your KiCad install using the check command below, because parts will not resolve without it, and note that output backends currently target KiCad 5 through 10.

## FAQ

### How do I install SKiDL?

Run `pip install skidl`. The setup script requires Python 3.6 or later, and optionally you should set KICAD_SYMBOL_DIR so parts can resolve against your KiCad symbol libraries.

### Why does SKiDL report no libraries found or symbol resolution errors?

KICAD_SYMBOL_DIR is unset or points at the wrong path, so parts do not resolve. The path differs by install method: /usr/share/kicad/symbols for a Linux package install, a Flatpak path under /var/lib/flatpak/app/org.kicad.KiCad, /Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols for Homebrew on macOS, and C:\Program Files\KiCad\8.0\share\kicad\symbols on Windows.

### How do I convert an existing KiCad design to SKiDL?

Use the netlist_to_skidl tool, which the package registers as a console script pointing at skidl.scripts.netlist_to_skidl_main. The README lists this as the route for converting existing KiCad designs.

### Which KiCad versions does SKiDL support?

The README describes editable KiCad schematic output for KiCad 6 through 10, and the troubleshooting section states SKiDL supports KiCad 5 through 10. If newer library files fail to parse, it suggests upgrading SKiDL with `pip install --upgrade skidl`.

### What does ERC() check in SKiDL?

The README names three classes: unconnected pins, drive conflicts and power connection errors. Design-level mistakes such as wrong values or missing parts are not part of electrical rules checking.

### What outputs can SKiDL generate from one design?

Netlists for PCB layout tools, XML for bills of materials, SVG or DOT diagrams for documentation, and editable KiCad schematics. The same source can also be run through SPICE for simulation.

## Sources

- [devbisme/skidl on GitHub](https://github.com/devbisme/skidl)
- [License: MIT](https://github.com/devbisme/skidl/blob/master/LICENSE)
- [Project website](https://devbisme.github.io/skidl/)
- [README](https://github.com/devbisme/skidl/blob/master/README.md)
- [Releases](https://github.com/devbisme/skidl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/devbisme-skidl
