Web Gerber Viewer — generate static PCB viewer sites from Gerber files
Project description
WGV — Web Gerber Viewer
Generate fully static, interactive PCB viewer website from Gerber manufacturing files. Open the result in any browser, no dynamic server required.
Features
- Render all copper, silk, mask, paste, drill, and outline layers
- Client-side Canvas rendering with d3-zoom pan/zoom/pinch
- Toggle individual layers on/off
- Top and bottom view (mirrored) with per-side layer defaults
- BOM and placement CSV overlay with component markers
- Search components by reference designator or value (Enter to select first match)
- Click component to show details, click search result to auto-switch view side and zoom to component
- Distance measurement tool (right-click to start, left or right-click to finish) with on-canvas label
- Cursor position readout in mm and mils
- Live placement offset adjustment in the viewer
- Tested with KiCad and Allegro exports, may support other tools by luck.
Result
Limitations
Sometimes, coordinates for drills, component placement and gerbers are not using the same origin. wgv tries hard to reconcilate them but may fail. This is the reason there are offset adjustment inputs in the final page. Default offset can also be overridden at generation time.
Installation
Requires Python 3.13+. No native dependencies — rendering is done client-side in the browser.
pip install -e ".[dev]"
Usage
Generate a viewer
# From a directory of Gerber files
wgv generate gerbers/ -o output/
# From a zip file with BOM and placement
wgv generate board.zip -o output/ \
--bom board-bom.csv \
--placement board-xy.csv
# Override auto-detected placement offset
wgv generate board.zip -o output/ \
--bom bom.csv --placement xy.csv \
--placement-offset 0.5 -15.5
# Explicit zoom level (default: auto, targeting 0.5 mil/pixel)
wgv generate board.zip -o output/ --zoom-max 8
Then open output/index.html in a browser. For local viewing,
serve with:
python3 -m http.server -d output/ 8000
# Open http://localhost:8000
Diagnostics
Inspect coordinate systems and auto-detected offset before generating:
wgv info board.zip --bom bom.csv --placement xy.csv
Outputs bounding boxes (gerber, edge cuts, drill, placement),
axis directions, size comparisons, and the correction offset.
Use --json for machine-readable output.
Viewer controls
| Action | Effect |
|---|---|
| Scroll / pinch | Zoom |
| Drag | Pan |
| Top / Bottom buttons | Switch view side (layers + flip) |
| Layer checkboxes | Toggle layer visibility |
| Search box (+ Enter) | Find component by ref or value |
| Click on component | Show component details popup |
| Right-click | Start / finish distance measurement |
| Left-click (while measuring) | Finish distance measurement |
| Escape | Clear measurement |
| Placement offset dX/dY | Nudge component markers in real-time |
Supported formats
Gerber files: RS-274X from KiCad, Allegro, Altium, Eagle, and most other EDA tools. Layer identification uses Gerber X2 attributes when available, with filename-based fallback.
Drill files: Excellon format (.drl, .xln), including Allegro
routed slots (.rou).
BOM CSV: Auto-detects column headers. Supports grouped references
(C1, C2, C3), tab or comma delimited, with optional preamble rows.
Placement CSV: Auto-detects columns for reference, X, Y, rotation,
and side. Handles comma decimal separators, mil/mm auto-detection,
and KiCad/Allegro naming conventions (SYM_MIRROR = YES/NO for side).
Project structure
src/wgv/
├── cli.py # Click CLI (generate, info)
├── board.py # Board model, placement offset detection
├── gerber/
│ ├── parser.py # Gerber/drill loading, layer identification
│ └── layers.py # Layer types, colors, z-ordering
├── csv/
│ ├── bom.py # BOM CSV parsing
│ ├── placement.py # Placement CSV parsing
│ └── merge.py # BOM + placement merge
├── render/
│ ├── extents.py # Board-to-tile coordinate mapping
│ └── primitives_export.py # Gerber primitive → JSON serialization
└── site/
├── generator.py # Static site assembly
└── static/ # HTML/JS/CSS + vendored d3-zoom
License
MIT
Notes
This project has been mostly vibe-coded using Claude Code from Anthropic. Coding manually would have been more-or-less the same but would have taken 10x the time.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wgv-0.1.0.tar.gz.
File metadata
- Download URL: wgv-0.1.0.tar.gz
- Upload date:
- Size: 908.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b2daa2dc9258457d6f7cd3bd9b93094c204c72af018601f735d04a91e0eb27b
|
|
| MD5 |
34482cfd65b5e139cf5f161201e54fc5
|
|
| BLAKE2b-256 |
9047be8f16883147a9293192c877dcc5d8d647135e3989664b08ec8a6ffbca17
|
File details
Details for the file wgv-0.1.0-py3-none-any.whl.
File metadata
- Download URL: wgv-0.1.0-py3-none-any.whl
- Upload date:
- Size: 65.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
453d613491edcdc36f481f6cfd5fbd273e7cceae4be45c89bd8cd516f326de94
|
|
| MD5 |
a6d4e78e319656b8b67e6d750bb39192
|
|
| BLAKE2b-256 |
920fa0156cde7b39e546e23c5deb47f9969ae7fab8a00f2943a19fbdae1c23d3
|