Web-based PCB boardview viewer for board-level repair. Fourteen boardview formats and the matching PDF schematic, side by side, in a browser. GPU-accelerated rendering, dockable panels, self-hosted via Docker. Free, AGPL-3.0.
A polished overview with screenshots lives at https://www.ripperdoc.de/boardripper/. This README is the developer- and operator-facing companion: stack details, Docker setup, build instructions, license notes.
Bring your own files. BoardRipper is the viewer only — it does not ship with any boardview files, schematics, or PDFs. The bundled board database is reference metadata (board numbers and device models), no copyrighted content.
Discord: https://discord.gg/BYEkKTMNNY — the RipperDoc server.
You can request features and tools there, or on GitHub — whichever you prefer. There is also a small repair community on the server.
Besides the Docker build there's a lite build: the full viewer/inspector running entirely client-side, no backend. Open your own boardview files and PDFs locally — nothing is uploaded, nothing is stored server-side. There's no shared library, board database, or self-update (those need the backend), but all rendering, inspection, net-highlight, multi-layer, themes, and PDF viewing work.
- Open it now — https://www.ripperdoc.de/boardripper/web/. Runs in the browser; installable as an offline PWA. An Offline copy button (top-right) downloads the single-file build.
- Offline single file — boardripper-lite.html (~7 MB). Save it and open it from any browser — fully offline, no server, no internet. Copy it to a USB stick for the bench.
Same codebase as the Docker build — npm run build:lite / npm run build:offline in src/frontend/. See src/frontend/LITE_BUILD.md.
- GPU-accelerated rendering — PixiJS v8 / WebGL, 10,000+ components at 60 fps on a modern GPU. Bench-tested down to Intel HD 4000-era integrated graphics (10–30 fps).
- Fourteen board formats — see table below. Both
.cadand.brdare shared extensions; BoardRipper sniffs file content to pick the right parser. - PDF schematic, in sync — pan, zoom, text search, bookmarks, night mode. Right-click a net on the board to search it in the schematic.
- Multi-board tabs — open several boards at once, switch between them.
- Multi-layer support — show/hide top, bottom, and inner layers independently. Butterfly mode shows top and bottom side by side.
- Net highlight — click a pin and the whole net lights up across the board. Chain-adjacent mode walks through neighbouring nets too.
- Part comparison — put one component's pinout next to the same chip on another open board, pin by pin. Where the net names differ, BoardRipper checks what each net actually touches and reads the naming conventions boards use — a pin marked unused, a rail written two ways — so a board that was only renamed does not read as a fault. Optionally marks the differing pins on the board itself.
- Touch input — pinch-zoom, drag-pan, tap to select. Usable on a tablet at the bench.
- Customizable colors — per-net rules by name pattern (e.g.
GND,VCC,PP*), per-component-type fills (R / C / L / U / Q / D / J), per-layer colors, label / pin / outline tuning. Live preview before applying. - Multi-line search — each line is an extra AND-filter, useful when a component carries value and voltage on separate label lines (
20uF⨯10V⨯C12*). - Drag-and-drop import — drop a board file or a folder onto the window and it loads. To persist drops across container restarts, mount a writable folder at
/library/incoming(see Docker setup). - Board library — scan folders, browse by board number or model. Filenames are auto-sorted; board numbers, manufacturers, and revisions are parsed automatically.
- Board database with heuristics — a bundled reference DB maps board numbers to manufacturer / ODM / laptop or phone model and groups boards by device.
- PDF auto-link — boards and their schematics get matched up automatically when both are present in the same library.
- IndexedDB cache — re-open without re-parsing.
- Self-update — one-click signed update from the toolbar. No GitHub token required; updates are signed with an offline Ed25519 key and verified by the running container before install.
- Panel system — Dockview: dockable, floating, and popout-to-new-window panels.
- Component Info (pins list, metadata)
- Net List (searchable, click to highlight)
- Search Results
- PDF Viewer
- Settings (live preview mockup, per-net color rules, label/pin/outline tuning)
- Debug Panel (scoped log viewer, frame-time)
- Electron desktop wrapper — standalone macOS (universal + legacy) and Windows builds.
| Format | Extension(s) | Description | Spec |
|---|---|---|---|
| BVR1 | .bvr / .bv |
Tab-delimited boardview, coordinates ×1000 → mils | BVR_FORMAT.md |
| BVR3 | .bvr / .bv |
Keyword-value boardview, relative pin coordinates | BVR_FORMAT.md |
| BRD | .brd |
Apple / Mac repair, bit-rotation obfuscated binary | BRD_FORMAT.md |
| BDV | .brd / .bdv |
Plain-text boardview (BRDOUT / NETS / PARTS / PINS / NAILS) | BDV_FORMAT.md |
| BDV ASC | .bdv |
Honhan / Tebo-ICT obfuscated multi-section ASC (line-key cipher) | BDV_ASC_FORMAT.md |
| FZ | .fz |
ASUS, RC6-encrypted, zlib-compressed | FZ_FORMAT.md |
| GenCAD | .cad |
GenCAD 1.4 PCB interchange (text) | CAD_FORMAT.md |
| Mentor Neutral | .cad |
Mentor Boardstation neutral file (Samsung / Quanta / Compal exports) | MENTOR_NEUTRAL_FORMAT.md |
| XZZ | .pcb |
XZZ PCB, DES-encrypted boardview | XZZ_FORMAT.md |
| TVW | .tvw |
Teboview binary, multi-layer + traces + drill data | TVW_FORMAT.md |
| Cadence Allegro BRD | .brd |
Cadence Allegro PCB binary, v16.x / v17.x / v18.x | ALLEGRO_BRD_FORMAT.md |
| ↳ Allegro v15.x | .brd |
Same parser family, partial coverage, still in beta | ALLEGRO_V15_FORMAT.md |
| Altium PCB | .PcbDoc / .CMPcbDoc / .CSPcbDoc |
Altium Designer 6.0+, Circuit Maker / Circuit Studio; binary CFB + ASCII v5.0 | ALTIUM_PCB_FORMAT.md |
| KiCad | .kicad_pcb |
KiCad 4–9 board file: parts, pins, nets, outline with cutouts, tracks, vias, copper pours | KICAD_PCB_FORMAT.md |
| EAGLE | .brd |
Autodesk / CadSoft EAGLE 6.0+ XML board; parts resolved through library packages | EAGLE_BRD_FORMAT.md |
The full, always-current list lives in Settings ▸ Shortcuts (and on the home-screen Getting Started card). The headline shortcuts:
| Open board / PDF | ⌘O / ⌘P (Mac) · Ctrl+O / Ctrl+P (Win/Linux) |
| Find (selection-aware) | ⌘F / Ctrl+F — prefills PDF search with the selected component or net |
| Pan board / PDF | W A S D or Alt+arrows |
| Rotate board | Q / E (CCW / CW) or ⌘← / ⌘→ |
| Mirror board | ⌘↑ / Ctrl+↑ |
| Flip layer (top ↔ bottom) | Space |
| Zoom in / out | Shift+W / Shift+S (centred on canvas) |
| Toggle Library sidebar | ~ — the physical key left of 1 (Backquote / IntlBackslash); works on US, German, and most other layouts |
| Jump board ↔ PDF | Tab |
| PDF page nav | PgUp / PgDn (or ⌘↑ / ⌘↓ on Mac) |
The keyboard pan and zoom step sizes are configurable in Settings ▸ Navigation ▸ Keyboard pan / zoom. The right-click context menu adds a top-row icon strip with Copy net / Copy part / Search net / Search part (board) and Copy / Search Web (PDF text) — search opens Google in a new tab.
Layout note. WSAD/QE/Shift+WS bind to the printed letter on your keyboard, so on AZERTY layouts the keys are physically Z/Q/S/D rather than the W/A/S/D positions — a layout-aware remapping is on the roadmap. The
~library toggle is layout-independent.
| Layer | Technology |
|---|---|
| Rendering | PixiJS v8 + pixi-viewport v6 (WebGL) |
| Frontend | React 19 + TypeScript + Vite 7 |
| Panels | Dockview v5 |
| Backend | Go (net/http stdlib) |
| Container | Docker multi-stage, scratch-based, ~25 MB image / ~13 MB compressed |
| Desktop | Electron (macOS universal + Windows) |
| Tests | Playwright (Chromium headless) |
BoardRipper is primarily a server you run on a NAS or host machine and access from any browser on your network. Standalone binaries and desktop Electron wrappers are available as alternatives.
docker compose up -d # the checked-in compose file BUILDS the image from source (build: .)
# → http://localhost:8081It mounts ./library, which starts empty — put your board folders in there or edit the
volumes: block to mount them read-only (see Docker setup). On first visit the app asks to
index the library and offers automatic board↔PDF linking and the OpenBoardData download.
Or pull directly:
docker pull ghcr.io/alexeyinwerp/boardripper:latestMount your board-file folders under /library to expose them in the Library panel — see Docker Setup below.
git clone https://github.com/AlexeyInwerp/BoardRipper.git
cd BoardRipper
# Build the frontend bundle:
cd src/frontend && npm install && npm run build && cd ../..
# Run the Go server pointing at the built bundle (go.mod lives in src/backend):
cd src/backend
STATIC_DIR=../frontend/dist DATA_DIR=../../data LIBRARY_DIR=/path/to/boards go run .
# → http://localhost:8080The released artifact is the Docker image (above) — no per-platform standalone binaries are published. If you need a portable binary, build the Go server with cd src/backend && CGO_ENABLED=0 go build -o boardripper . and ship it next to the dist/ directory and a STATIC_DIR= env var. Set LIBRARY_DIR to the folder to index — without it the server indexes DATA_DIR. Self-update only works in Docker (it needs the host's Docker socket).
# Frontend (hot reload)
cd src/frontend && npm install && npm run dev # http://localhost:5173
# Backend (separate terminal) — the Vite dev proxy targets port 1336
cd src/backend && PORT=1336 go run . # http://localhost:1336services:
boardripper:
image: ghcr.io/alexeyinwerp/boardripper:latest # the repo's own docker-compose.yml says `build: .` instead
# The image ships USER 65532:65532 (distroless `nonroot`) so a hypothetical
# RCE doesn't own your bind-mounted /data. The default `docker compose up`
# flow creates ./data as root on Linux hosts (Docker daemon runs as root),
# which UID 65532 can't then write — the container exits at databank.Open
# with "unable to open database file". Override to root for the compose
# path, matching what NASdeploy.sh already does. Alternatively, remove this
# line and either (a) `chown -R 65532:65532 ./data` before `up -d`, or
# (b) switch ./data to a named volume — Docker initializes named volumes
# from /data inside the image (pre-chowned to 65532 in the Dockerfile).
user: "0:0"
ports:
- "8081:8080" # access at http://your-host:8081
volumes:
- ./data:/data # uploaded board files + cache persist here
# Your library: mount EVERYTHING read-only (:ro) by default.
- /path/to/MacBooks:/library/MacBooks:ro
- /path/to/iPhones:/library/iPhones:ro
- /path/to/Schematics:/library/Schematics:ro
# The ONLY writable mount the container should ever see:
- /path/to/incoming:/library/incoming:rw
# Docker socket (required for self-update — see Self-Update below):
- /var/run/docker.sock:/var/run/docker.sock
environment:
- PORT=8080
restart: unless-stopped
mem_limit: 2g # hard cap; 512M boot-fails with SQLite OOM at databank open
# environment also accepts:
# - PDFINDEX_POOL_MAX=2 # max concurrent pdfium/wazero PDF-index workers;
# # reduce to 1 on a NAS with <1 GB free RAMThe Library panel browses the /library directory inside the container. Mount your board-file folders as subdirectories of /library:
-v /nas/boards/MacBooks:/library/MacBooks:ro
-v /nas/boards/iPhones:/library/iPhones:ro
-v /nas/schematics:/library/Schematics:ro
-v /nas/incoming:/library/incoming:rw
These appear as top-level folders in the Library panel. Use :ro for read-only by default. /library/incoming is the only path BoardRipper needs to be able to write to — that's where drag-dropped files land. The container does not need write access to your existing board folders, your schematics, or anything else.
- Download
boardripper-<version>.tar.gz(orlatest.tar.gz) from https://www.ripperdoc.de/boardripper/releases/ - SSH into your NAS and load the image:
docker load < boardripper-<version>.tar.gz
- Create the container.
--user 0:0is needed because DSM creates the data folder root-owned and the image runs as UID 65532 otherwise (the container would exit with "unable to open database file");/library/incomingis where drag-dropped files land:docker run -d \ --name boardripper \ --user 0:0 \ -p 8090:8080 \ --memory 2g \ -v /volume1/docker/boardripper/data:/data \ -v /volume1/your-boards/MacBooks:/library/MacBooks:ro \ -v /volume1/your-boards/iPhones:/library/iPhones:ro \ -v /volume1/docker/boardripper/incoming:/library/incoming:rw \ -v /var/run/docker.sock:/var/run/docker.sock \ -e PORT=8080 \ --restart unless-stopped \ ghcr.io/alexeyinwerp/boardripper:latest
- Open
http://your-nas-ip:8090
BoardRipper can update itself when running in Docker:
- Click the version badge in the toolbar to check for updates.
- If an update is available, click Update & Restart.
- The container pulls the new image and restarts automatically.
Requires:
- Docker socket mounted (
-v /var/run/docker.sock:/var/run/docker.sock).
The signed release manifest is fetched from https://www.ripperdoc.de/boardripper/manifest.json and verified against an Ed25519 public key compiled into the running binary before any I/O on the body — a hijacked mirror cannot deliver a forged update. Once the manifest verifies, the image itself is pulled by content-addressed digest from ghcr.io/alexeyinwerp/boardripper@sha256:…; the signed tarball mirror is the fallback if GHCR is unreachable. The pipeline also enforces a monotonic counter (replay defence), a 30-day freshness window, a 90-day expiry, and a min_supported_version downgrade defence. See docs/RELEASE_RUNBOOK.md for the maintainer-side release procedure.
For installs that can't reach the registry or the mirror (firewalled networks, air-gapped shops, recovery from a broken self-update):
- Download
latest-update.tarfrom https://www.ripperdoc.de/boardripper/releases/latest-update.tar (signed bundle: manifest + signature + image, ~13 MB). - Drag the file anywhere on the BoardRipper UI.
- Confirm the prompt; the running container verifies the signature, applies the update, and restarts.
- The browser reloads after ~30 s.
Same trust envelope as the in-app updater — the manifest signature is what grants trust, the file itself is treated as untrusted bytes until verification passes.
docker pull ghcr.io/alexeyinwerp/boardripper:latest
docker compose down && docker compose up -dOr with a downloaded tarball:
docker load < boardripper-docker-<new-version>.tar.gz
docker compose down && docker compose up -dHistorical releases live at https://www.ripperdoc.de/boardripper/archive.html — Docker tarballs and signed drop-bundles for v0.19.0 onward, with per-version source links for everything older. The GitHub Releases page intentionally lists only the current release; the archive is the canonical "give me an older version" landing page.
A handful of versions are also kept on GHCR (v0.19.0, v0.19.5, v0.20.5, v0.20.8) for direct docker pull — see the archive table for which ones are still pull-able vs. tarball/source-only.
Prebuilt Electron wrappers are published with every release (BoardRipper-macOS-universal-<version>.zip, BoardRipper-Windows-x64-<version>.zip). They run the same Go backend + React frontend inside an Electron shell. The Docker / server path is the primary way to deploy BoardRipper; the desktop wrapper is here for single-machine use.
The wrappers are unsigned, so macOS Gatekeeper and Windows SmartScreen will warn on first launch:
- macOS — after unzipping, run
xattr -cr /Applications/BoardRipper.app(or wherever you extracted it), then double-click. On macOS < 15 you can also right-click → Open → Open once, or use System Settings → Privacy & Security → Open Anyway after the first failed launch. - Windows — SmartScreen shows "Windows protected your PC". Click More info → Run anyway.
cd desktop
npm install
node build-all.mjs # builds macOS universal + legacy + Windows
node build-all.mjs --mac # macOS only
node build-all.mjs --win # Windows onlyOutput in desktop/out/ (macOS), desktop/out-legacy/ (macOS legacy), desktop/out-win/ (Windows).
BoardRipper is released under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for the full text.
This project incorporates code derived from KiCad (GPL-3.0) — specifically the Cadence Allegro BRD reader in src/frontend/src/parsers/allegro/, transliterated from KiCad's pcbnew/pcb_io/allegro/ C++ source — which is why AGPL-3.0 was chosen: it is compatible with GPL-3.0 and additionally closes the "SaaS loophole" by requiring source availability to users who interact with a hosted instance over a network.
For a complete list of third-party sources, libraries, and attributions, see THIRD_PARTY.md.
BoardRipper exists because of the reverse-engineering work already done by the boardview community. Each entry below was consulted during development; full attribution and license details are in THIRD_PARTY.md.
Community reverse engineering incorporated into BoardRipper
- Sean Johnson (@sjohnson1021) — XZZ format
work, reverse-engineered independently and reported with full evidence:
the through-hole drill diameter in the pin sub-block and the slot
geometry for oblong through-holes (#32),
the component value carried in a part's second label block
(#27), the fact that
the oblong-pad pen is the shorter axis rather than a fixed field, the via
layer-span correction, and the
isOblongRoundPad/drawPinShape/emitPartOutlineShaperefactor that unified seven copies of one decision. Attribution is repeated at each site in the source. He also maintains XZZPCB-Layer-Viewer and an ImHex pattern for the format.
Parser references
- KiCad (GPL-3.0) — Cadence Allegro BRD reader, transliterated to TypeScript. The reason BoardRipper as a whole is AGPL-3.0.
- OpenBoardView (MIT) — reference implementations for BVR1/BVR3, BRD (Apple), BDV (plain-text), BDV ASC (Honhan / Tebo-ICT), FZ (ASUS), GenCAD, XZZ.
- eagleview by Pavel Kovalenko (MIT) — TVW / Teboview parser source.
- brd_parser by Jeff Wheeler (MIT) — cross-validation reference for Allegro block layout.
- piernov's Honhan BDV gist & OpenBoardView issue #2 — identified the BDV ASC signature and line-key cipher.
- Mentor Boardstation Neutral — original reverse engineering, no third-party code or text incorporated.
- Cryptographic standards — RC6 by Rivest/Robshaw/Sidney/Yin (FZ), DES / FIPS PUB 46-3 (XZZ). GenCAD 1.4 has no canonical online specification — see docs/formats/CAD_FORMAT.md for the BoardRipper interpretation.
Rendering & runtime
- PixiJS (MIT) — WebGL renderer
- pixi-viewport (MIT) — pan/zoom/culling
- React (MIT) — UI framework
- Vite (MIT) — build pipeline
- Dockview (MIT) — dockable / floating / popout panel system
- pdf.js (Apache-2.0) — PDF rendering and text extraction
- pdf-lib (MIT) — PDF manipulation
- opentype.js (MIT) — font glyph extraction
- Tabler Icons (MIT) — icon set
Backend
- Go standard library (BSD-3-Clause)
- modernc.org/sqlite (BSD-3-Clause) — pure-Go SQLite driver
- github.com/klippa-app/go-pdfium (MIT) — PDF text extraction for the FTS5 index (embedded
pdfium.wasm) - github.com/tetratelabs/wazero (Apache-2.0) — pure-Go WebAssembly runtime hosting
pdfium.wasm - aead.dev/minisign (MIT) — Ed25519 update-manifest signature verification
- golang.org/x/text (BSD-3-Clause) — Unicode NFKC normalisation for watermark matching
Desktop
- Electron (MIT), @electron/packager (MIT), @electron/universal (MIT)
Corrections and missing attributions are welcome — open an issue, or email [email protected].
BoardRipper is not hand-written. The codebase — parsers, renderer, panels, backend — was generated with Claude Code, working from format specs and reference implementations from the boardview community. I review, test, and direct it; the lines of code came out of an LLM.
Treat that as you would any AI-assisted software: it works on the boards I've tested, it has bugs I haven't found yet, and the right level of trust is "a useful viewer, not a forensic tool." Bug reports welcome.
- Discord: @inwerp on the RipperDoc server — feature requests, questions about deployment or file formats, and a small repair community.
- Bugs and feature requests: file an issue on GitHub, or ask on Discord.
- Email: [email protected].
If BoardRipper saves you time, buy me a coffee.



