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, *.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.