kicad-pcb-viewer — 2D viewer for .kicad_pcb files
Public Unreviewed2D PCB viewer for .kicad_pcb files in a Hydrogen webview. Pan, zoom, toggle layers, flip to inspect the back side. Stdlib Python, ~22 KB binary.
kicad-pcb-viewer
A 2D viewer for .kicad_pcb files, rendered as SVG inside a Hydrogen webview
panel. Use when the user wants to inspect a KiCad PCB without opening
KiCad itself, see traces / pads / silk on a flat board view, or share what
a board looks like in the editor.
For 3D inspection (.glb / STEP), use the existing 3D viewers — this app is deliberately 2D-only.
Trigger phrases
- "view this kicad pcb", "open .kicad_pcb", "show me the board"
- "what does this PCB look like", "preview the pcb", "render the board"
- "view layer F.Cu / B.Cu / silkscreen", "show pcb layers"
- "kicad-pcb-viewer", "pcb viewer", "open the board layout"
Quick start
kicad-pcb-viewer view path/to/board.kicad_pcb
This starts the server, opens a Hydrogen webview tab in a non-VSCode pane,
and renders the board. Pan with click-drag, zoom with the scroll wheel,
toggle layers in the sidebar, click Fit to reset, click Flip to mirror.
Subcommands
| Command | Purpose |
|---|---|
view <path> [--port N] |
Start server + open webview tab. Default. |
serve <path> [--port N] |
Start server only (no tab). |
shutdown [--port N] |
Stop a running viewer. |
install |
Deploy this SKILL.md to ~/.claude/skills/kicad-pcb-viewer/. |
version |
Print version. |
Default port: 9100. The server is single-instance per port.
HTTP API (AI-drivable)
Everything the UI does is also reachable via HTTP. Useful for scripting view changes, taking annotated screenshots, or driving from other tools.
| Method | Path | Action |
|---|---|---|
| GET | /state |
Current phase, file, stats, bbox, layer visibility. |
| GET | /board |
Full parsed board JSON (footprints, pads, traces, vias, zones, gr). |
| GET | /layers |
Per-layer info: idx, kind, alias, visible. |
| POST | /layers |
Body: {name: bool, …} — toggle layer visibility. |
| POST | /load |
Body: {path: "..."} — open a different .kicad_pcb. |
| POST | /fit |
Reset view to fit the board. |
| POST | /flip |
Mirror board horizontally (B-side viewing). |
| GET | /console |
Recent UI-side console messages (forwarded). |
| POST | /eval |
Body: {code: "..."} — queue a JS snippet for the UI. |
| GET | /eval/pending |
UI poller calls this to get pending snippets. |
| POST | /shutdown |
Graceful exit. |
Example: get stats for a board without opening a tab.
kicad-pcb-viewer serve board.kicad_pcb --port 9100 &
sleep 1
curl -s http://127.0.0.1:9100/state | jq '.stats'
curl -s -X POST http://127.0.0.1:9100/shutdown
Example: hide every layer except Edge.Cuts for a board-outline screenshot.
curl -X POST http://127.0.0.1:9100/layers -H 'Content-Type: application/json' \
-d '{"F.Cu":false,"B.Cu":false,"F.SilkS":false,"B.SilkS":false,"Edge.Cuts":true}'
What it parses
The s-expression parser handles:
(footprint …)with(at …)placement, rotation, and child pads(pad …)shapes: rect, roundrect, circle, oval (drilled or SMD)(segment …),(arc …)copper traces with width(via …)with size + drill(zone …)filled polygons (post-fill state if present, else outline)(gr_line/arc/circle/rect/poly …)top-level graphics(fp_line/arc/circle/rect/poly …)footprint graphics (silk, fab, courtyard)(layers …)definitions and (pad-side)(layers …)lists with*.Cu,*.Mask,*.Pastewildcards expanded
What it does NOT do (yet):
- Schematic rendering (
.kicad_sch) - Net highlighting / cross-probing
- Real-time sync if the file changes on disk (call
POST /loadto reload) - Refdes / value labels overlaid on footprints
Pane placement
The viewer ALWAYS opens in a non-VSCode pane. If a non-VSCode pane already
exists in the workspace, the tab joins that pane; otherwise the VSCode pane
is split vertically and the tab lands in the new pane. Never as a tab inside
the VSCode pane itself. See skills/app-creator §4.
Files in this app
bin/kicad-pcb-viewer— Python CLI entry point.src/parser.py— s-expression tokenizer + per-layer extractor.src/server.py— HTTP server with all endpoints.src/ui.html— single-file frontend (SVG render, pan/zoom, layer toggles).docs/icon.svg— brand-teal favicon (also embedded as the tab icon).samples/— checked-in reference boards for testing.
Repo
adom-inc/kicad-pcb-viewer (private). Releases attach a single-file
zipapp kicad-pcb-viewer-linux that runs on any Python 3.10+ system.
# kicad-pcb-viewer
A 2D viewer for `.kicad_pcb` files, rendered as SVG inside a Hydrogen webview
panel. Use when the user wants to **inspect a KiCad PCB without opening
KiCad itself**, see traces / pads / silk on a flat board view, or share what
a board looks like in the editor.
For 3D inspection (.glb / STEP), use the existing 3D viewers — this app is
deliberately 2D-only.
## Trigger phrases
- "view this kicad pcb", "open .kicad_pcb", "show me the board"
- "what does this PCB look like", "preview the pcb", "render the board"
- "view layer F.Cu / B.Cu / silkscreen", "show pcb layers"
- "kicad-pcb-viewer", "pcb viewer", "open the board layout"
## Quick start
```bash
kicad-pcb-viewer view path/to/board.kicad_pcb
```
This starts the server, opens a Hydrogen webview tab in a non-VSCode pane,
and renders the board. Pan with click-drag, zoom with the scroll wheel,
toggle layers in the sidebar, click `Fit` to reset, click `Flip` to mirror.
## Subcommands
| Command | Purpose |
|---|---|
| `view <path> [--port N]` | Start server + open webview tab. Default. |
| `serve <path> [--port N]` | Start server only (no tab). |
| `shutdown [--port N]` | Stop a running viewer. |
| `install` | Deploy this SKILL.md to `~/.claude/skills/kicad-pcb-viewer/`. |
| `version` | Print version. |
Default port: `9100`. The server is single-instance per port.
## HTTP API (AI-drivable)
Everything the UI does is also reachable via HTTP. Useful for scripting
view changes, taking annotated screenshots, or driving from other tools.
| Method | Path | Action |
|---|---|---|
| GET | `/state` | Current phase, file, stats, bbox, layer visibility. |
| GET | `/board` | Full parsed board JSON (footprints, pads, traces, vias, zones, gr). |
| GET | `/layers` | Per-layer info: idx, kind, alias, visible. |
| POST | `/layers` | Body: `{name: bool, …}` — toggle layer visibility. |
| POST | `/load` | Body: `{path: "..."}` — open a different `.kicad_pcb`. |
| POST | `/fit` | Reset view to fit the board. |
| POST | `/flip` | Mirror board horizontally (B-side viewing). |
| GET | `/console` | Recent UI-side console messages (forwarded). |
| POST | `/eval` | Body: `{code: "..."}` — queue a JS snippet for the UI. |
| GET | `/eval/pending` | UI poller calls this to get pending snippets. |
| POST | `/shutdown` | Graceful exit. |
Example: get stats for a board without opening a tab.
```bash
kicad-pcb-viewer serve board.kicad_pcb --port 9100 &
sleep 1
curl -s http://127.0.0.1:9100/state | jq '.stats'
curl -s -X POST http://127.0.0.1:9100/shutdown
```
Example: hide every layer except `Edge.Cuts` for a board-outline screenshot.
```bash
curl -X POST http://127.0.0.1:9100/layers -H 'Content-Type: application/json' \
-d '{"F.Cu":false,"B.Cu":false,"F.SilkS":false,"B.SilkS":false,"Edge.Cuts":true}'
```
## What it parses
The s-expression parser handles:
- `(footprint …)` with `(at …)` placement, rotation, and child pads
- `(pad …)` shapes: rect, roundrect, circle, oval (drilled or SMD)
- `(segment …)`, `(arc …)` copper traces with width
- `(via …)` with size + drill
- `(zone …)` filled polygons (post-fill state if present, else outline)
- `(gr_line/arc/circle/rect/poly …)` top-level graphics
- `(fp_line/arc/circle/rect/poly …)` footprint graphics (silk, fab, courtyard)
- `(layers …)` definitions and (pad-side) `(layers …)` lists with `*.Cu`,
`*.Mask`, `*.Paste` wildcards expanded
What it does NOT do (yet):
- Schematic rendering (`.kicad_sch`)
- Net highlighting / cross-probing
- Real-time sync if the file changes on disk (call `POST /load` to reload)
- Refdes / value labels overlaid on footprints
## Pane placement
The viewer ALWAYS opens in a non-VSCode pane. If a non-VSCode pane already
exists in the workspace, the tab joins that pane; otherwise the VSCode pane
is split vertically and the tab lands in the new pane. Never as a tab inside
the VSCode pane itself. See `skills/app-creator` §4.
## Files in this app
- `bin/kicad-pcb-viewer` — Python CLI entry point.
- `src/parser.py` — s-expression tokenizer + per-layer extractor.
- `src/server.py` — HTTP server with all endpoints.
- `src/ui.html` — single-file frontend (SVG render, pan/zoom, layer toggles).
- `docs/icon.svg` — brand-teal favicon (also embedded as the tab icon).
- `samples/` — checked-in reference boards for testing.
## Repo
`adom-inc/kicad-pcb-viewer` (private). Releases attach a single-file
zipapp `kicad-pcb-viewer-linux` that runs on any Python 3.10+ system.