Physical network documentation for home labs and small offices. Map your devices, ports, cable runs, patch panels, and racks — then keep a visual, searchable record of what's plugged into what, backed up with real photos of your gear.
CableMap is a self-hosted web app (Node + SQLite) with a dark, keyboard-friendly UI. It's built for the person who has traced one cable too many and wants to write it down once. As of v0.8.0 it also imports from your UniFi controller and DNS/DHCP servers, tracks device uptime, alerts you when something changes, and can print a PDF documentation pack.
| Dashboard | Racks |
|---|---|
![]() |
![]() |
| At-a-glance counts, quick search, and recent activity. | Front-of-rack "U" elevation with per-rack photos. |
| VLAN Manager |
|---|
![]() |
| Manage VLANs and see the connections assigned to each. |
Home labs grow organically. You add a switch, a NAS, an AP, a UPS — and six months later you can't remember whether port 14 on the core switch goes to the office wall jack or the garage. CableMap is a focused record-keeping tool for exactly that:
- Write down the trace — port A → patch panel → port B, with cable type, color, length, and VLAN.
- Prove it with a photo — attach pictures of the actual cable run, the device, or the whole rack.
- See it two ways — a fast searchable table for daily lookups, and a visual canvas + rack elevation for planning and documentation.
- Devices, ports & connections — full CRUD with a port-conflict-aware connection model (a port can only hold one active connection at a time).
- Bulk patching — patch a whole range of ports between two devices at once (switch 1–24 → panel 1–24), with a row-by-row preview and per-row conflict validation.
- Patch panel support — front/back port pairs are modeled as linked ports, so a cable trace follows through the panel automatically.
- Port trace algorithm —
GET /api/ports/:id/tracewalks the physical path hop-by-hop (including patch-panel pass-through and cycle detection). - Rack elevation view — a real "U" diagram driven by each device's rack position, with real front/rear device images (via the NetBox import), drag-to-reposition, and PNG export. Passive occupants (UPS, shelves, blank panels) take up space too.
- Connection-aware rack view — click a device in the elevation to see its cable runs drawn as arcs along the rack rail, color-coded by cable type, with runs that leave the rack tagged. The rack view answers "follow that cable" in physical space.
- NetBox devicetype-library import — search 5,000+ community device definitions (CC0) and import any model as an editable template with accurate ports, power outlets, and front/rear elevation images. Devicetype YAML flows both ways: upload a local .yaml, or export any template back to the library format. Half-U gear and pass-through patch panels import correctly.
- Rack layout import — bootstrap racks from a NetBox devices JSON export or a Rackula layout file: racks + placed devices (half-U supported), with template matching for types and images.
- LLDP/CDP link discovery — poll a managed switch over SNMP to learn what's plugged into what, and confirm the proposed links into real connections (optional
net-snmpdependency; managed gear only). - IPAM-lite — subnets (VLAN-linked) with live usage bars, per-address assignments, next-free suggestions, and one-click import of device management IPs.
- Cable schedule — a registry of every physical run (cable ID, from/to device+port+location, type, connector, color, length, VLAN) with CSV export; plus scannable device QR codes for field lookup.
- Asset & lifecycle — serial/asset tag/supplier/cost and purchase/warranty/EOL dates per device, with an Assets dashboard rolling up out-of-warranty, EOL-soon, and estimated fleet value.
- Multi-user & API tokens — admin/editor/viewer accounts (viewers read-only) and hashed API tokens for scripted access (
Authorization: Bearer/X-API-Key), on top of the env-configured bootstrap admin.
- UniFi controller import — pull UniFi devices & switch ports into your inventory and queue client uplinks as proposed links (reviewed in the same confirm-before-write queue as LLDP). Works with UniFi OS (UDM/UDR/Cloud Key Gen2+) and legacy software controllers.
- DNS/DHCP → IPAM import — a multi-source adapter for AdGuard Home, Pi-hole, Technitium, OPNsense, pfSense, MikroTik, UniFi, Firewalla, plus generic dnsmasq / ISC dhcpd / Kea CSV / hosts / CSV files. Preview a diff, then apply into IPAM. Pull from a live API or paste/upload the data.
- Uptime & latency history — the reachability monitor now records a time-series; device pages show a 24h uptime bar and latency sparkline, and the dashboard shows overall availability.
- Notifications & webhooks — opt-in alerts on device down/up, warranty/EOL approaching, or health regressions via ntfy, generic webhook, Discord, Slack, or email (SMTP), deduped so you're not spammed.
- PDF documentation pack — one-click branded PDF (device inventory, rack elevations, cable schedule, IPAM, power) for handoff, compliance, or an MSP deliverable.
- Canvas view — a React Flow topology map with device nodes, color-coded cable edges, draggable layout, VLAN/location filtering, live-status overlay, themes, uplink-aware auto-layout, and PNG/SVG export.
- Reachability monitoring — opt in per device (ping / HTTP / HTTPS / TCP) with live online/offline status in the list, on device detail, on the canvas, and on the dashboard, plus uptime history and optional notifications. A lightweight documentation aid, not a full NOC. Configurable sweep interval; set
MONITOR_INTERVAL_SECONDS=0to disable. - Network discovery — sweep a subnet (
/24–/30) to find live hosts (IP, MAC + vendor, hostname) and approve them into your inventory from a pending queue. Pings only; no port scanning. - Read-only share links — revocable, no-login "live view" links for a wall display or a colleague (structure + status + connections; no photos, no editing).
- Interop — JSON topology export (and a tokenized public feed) for other tools, plus an optional MCP server so an AI assistant can query the physical record.
- Power mapping & load budgeting — model UPS/PDU outlets and which device each one feeds (with receptacle types and estimated draw), give a power source its rated capacity, and watch a live load bar with overload warnings. Device detail shows an outlet map for power sources and a "powered by" panel for everything else.
- Health check — audits your documentation for inconsistencies: double-booked ports, rack-U overlaps, overloaded power sources, unmapped power, devices with no ports, and stale planned connections.
- Change history — an append-only timeline of every device, connection, and power change, with a global History page and a per-device view.
- Photos & documents — attach images (cable traces, device shots, rack photos) with auto-generated thumbnails, plus PDF spec sheets and Visio stencils. There's also a free-form photo gallery.
- Full backup & restore — one-click ZIP of all data + uploaded files, and a guarded restore.
- 344 built-in device templates across 25+ vendors — pick a model and the device form auto-fills make, type, rack height, ports, and (for UPS/PDU) outlets.
- Custom templates — create your own gear (manufacturer, model, OS/firmware, form factor, ports, photo, spec sheet, product URLs). Built-ins are read-only; your custom ones are fully editable down to individual ports.
- VLAN manager, full-text search, CSV import/export, and PDF port-map export.
- Role-based multi-user auth (admin / editor / viewer) with API tokens, dark-mode-only UI, mobile-friendly list/search views.
344 templates spanning networking, security, NAS, and power gear, including:
- Ubiquiti — the UniFi lineup (gateways, switches, access points, aggregation)
- Firewalls / NGFW — Fortinet (FortiGate/FortiSwitch/FortiAP, D/E/F gens), Palo Alto Networks (PA-200 → PA-5400), Cisco (ASA, Firepower, Secure Firewall), Cisco Meraki MX, Netgate/pfSense, OPNsense, Sophos XGS, SonicWall TZ, Protectli
- Switches / APs — Cisco Catalyst (1200/1300, 2960-X, 3850, 9200/9300) & Meraki MS/MR, TP-Link Omada, MikroTik, Netgear, Aruba Instant On
- NAS — Synology, QNAP, TrueNAS/iXsystems, Asustor, UGREEN, Drobo, plus custom DIY builds
- UPS / power — APC, CyberPower, Eaton, Tripp Lite, Vertiv (rackmount + tower/desktop), plus rack PDUs — all with outlet definitions
- Generic — patch panels, rackmount servers, UPS, shelves/drawers, blank rackspace, DIY
⚠️ Template port layouts are best-effort reference data to save you typing — not a guaranteed spec sheet. Every value is editable after you add a device, and you can create your own custom templates. Corrections via PR are welcome.
Need something not in the built-in library? Use Import from NetBox on the Templates page to pull any of 5,000+ community device definitions (ports, outlets, and rack images included).
| Layer | Technology |
|---|---|
| Frontend | React + Tailwind CSS, bundled with Vite |
| Canvas | React Flow (reactflow) |
| Charts | Inline SVG (no chart library) |
| Backend | Node.js 22 + Express |
| Database | SQLite via better-sqlite3 |
| Auth | express-session + bcrypt; multi-user roles + hashed API tokens |
| Images | sharp (server-side thumbnails) |
| Export | CSV + PDF (pdfkit) + QR (qrcode) |
| Optional | net-snmp (LLDP), nodemailer (email alerts), @modelcontextprotocol/sdk (MCP) |
Prerequisites: Node.js 22 LTS and npm. (It still runs on Node 20+, but Node 20 reached end-of-life in April 2026 — use 22.)
git clone https://github.com/breed007/CableMap.git
cd CableMap
# Install root, client, and server dependencies
npm run install:all
# Configure environment (change the secrets!)
cp .env.example .env
# edit .env → set SESSION_SECRET and ADMIN_PASSWORD
# Initialize the database (creates tables, seeds locations, VLANs, templates)
npm run db:init
# Run client (Vite) + server (Express) together
npm run dev- Frontend dev server: http://localhost:5173
- API: http://localhost:3000
Log in with the ADMIN_USERNAME / ADMIN_PASSWORD from your .env.
npm run build # builds the React app into server/public/
npm start # serves the app + API from Express on PORT (default 3000)cp .env.example .env # edit secrets
docker compose up -dThe app runs on port 3000 and stores everything (database, sessions, uploaded photos) in a named volume mounted at /data. See docs/deployment-docker.md for update, backup, and reset instructions.
Running Proxmox? Create a ready-to-go container in one line — run this on the Proxmox host as root:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/breed007/CableMap/main/scripts/proxmox-lxc-install.sh)"It spins up a Debian 13 LXC (defaults: 2 vCPU · 2048 MiB · 8 GiB, unprivileged), installs CableMap as a systemd service, and prints the URL plus a generated admin password. Pick Advanced at the prompt to change resources, hostname, or set a static IP. Update later by re-running pct exec <CTID> -- bash /root/lxc-setup.sh. Full details in scripts/README.md.
All configuration is via environment variables (see .env.example):
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP port |
SESSION_SECRET |
changeme |
Session signing secret — change this |
ADMIN_USERNAME |
admin |
Login username |
ADMIN_PASSWORD |
changeme |
Login password (plaintext, or a bcrypt hash) — change this |
DATA_DIR |
./data |
Directory for the DB, sessions, and uploads |
DB_PATH |
./data/cablemap.db |
SQLite database path |
MONITOR_INTERVAL_SECONDS |
60 |
Reachability sweep interval; 0 disables the background checker |
COOKIE_SECURE |
false |
Set true when behind an HTTPS reverse proxy (marks the session cookie Secure) |
HISTORY_RETENTION |
5000 |
Max history rows kept; older rows are pruned hourly (0 disables) |
UPTIME_RETENTION_DAYS |
30 |
Days of reachability samples kept for the uptime charts |
NOTIFY_COOLDOWN_MINUTES |
15 |
Minimum gap between repeat notifications for the same event |
PUBLIC_BASE_URL |
(request host) | Base URL embedded in device QR codes (set when behind a proxy) |
To use a hashed admin password instead of plaintext:
node -e "require('bcrypt').hash('your-password', 10).then(h => console.log(h))"
# paste the $2b$... output as ADMIN_PASSWORD- Linux (PM2 + Nginx/Apache):
docs/deployment-linux.md - Docker:
docs/deployment-docker.md
CableMap/
├── client/ React + Vite frontend
│ └── src/
│ ├── pages/ Dashboard, Devices, Connections, Canvas, Racks, Templates, …
│ ├── components/ Sidebar, Modal, PhotoUploader, DocumentUploader, icons
│ └── utils/ API client, color/label maps
├── server/ Express backend
│ ├── db/ schema, seeds (templates), init/migrations
│ ├── routes/ devices, ports, connections, vlans, attachments, templates, …
│ └── utils/ tracePath (port-trace algorithm)
├── docs/ Deployment guides
└── data/ SQLite DB + uploads (gitignored)
All routes are under /api/ and require an authenticated session.
GET|POST /api/locations GET /api/locations/:id (rack elevation)
GET|POST /api/devices PUT /api/devices/:id/position
POST /api/devices/:id/ports/bulk-create
GET|PUT|DELETE /api/ports/:id GET /api/ports/:id/trace
GET|POST /api/connections POST /api/connections/bulk (bulk patch)
GET|POST /api/vlans
GET|POST|PUT|DELETE /api/device-templates (custom templates editable; built-ins read-only)
GET|POST|PUT|DELETE /api/attachments (images + PDF/Visio docs)
GET|POST|PUT|DELETE /api/power/outlets POST /api/power/outlets/bulk-create
GET|POST|PUT|DELETE /api/power/connections (outlet → device power mapping)
GET /api/history GET /api/history/device/:id
GET /api/health (consistency / completeness checks)
POST /api/devices/:id/check POST /api/monitor/check-all (reachability)
POST /api/discovery/scan GET /api/discovery POST /api/discovery/:id/import
GET /api/netbox/search?q= POST /api/netbox/import (devicetype-library)
POST /api/netbox/import-yaml GET /api/device-templates/:id/netbox.yaml
POST /api/import/rack (NetBox / Rackula rack layouts)
GET /api/elevations/:file POST /api/elevations/upload
GET|POST|PUT|DELETE /api/ipam/subnets /api/ipam/addresses (IPAM)
POST /api/lldp/poll GET /api/lldp POST /api/lldp/:id/import (link discovery)
GET /api/cable-schedule GET /api/cable-schedule/export.csv
GET /api/qr/device/:id.svg GET /api/assets/lifecycle
GET /api/monitor/history/:id GET /api/monitor/uptime (uptime + latency)
GET|POST|PUT|DELETE /api/notifications/channels /api/notifications/rules (admin only)
POST /api/imports/preview POST /api/imports/apply POST /api/imports/sources/:id/run (DNS/DHCP)
POST /api/unifi/test POST /api/unifi/preview POST /api/unifi/import
GET /api/export/documentation.pdf (documentation pack)
GET|POST|PUT|DELETE /api/users /api/tokens (admin only)
GET|POST|DELETE /api/share (read-only share links)
GET /api/public/:token/snapshot GET /api/public/:token/topology.json (no auth)
GET /api/export/topology.json (interop)
GET /api/backup/export POST /api/backup/import
GET /api/search?q= GET /api/summary
POST /api/import/connections GET /api/export/connections
GET /api/export/device/:id/pdf
CableMap ships an experimental MCP server that exposes the physical record as read-only tools (list_devices, get_device, list_connections, search, topology) so an AI assistant can answer questions like "what's plugged into the core switch?".
cd server
npm install @modelcontextprotocol/sdk # optional dependency
DB_PATH=../data/cablemap.db npm run mcp # stdio MCP serverIt reads the SQLite database directly (via Node's built-in driver) and doesn't require the web server to be running.
The server has a test suite built on Node's built-in test runner and node:sqlite — no external dependencies to install. Requires Node 22+ for testing (which is also the recommended runtime; the app still runs on Node 20+).
cd server && npm testCI (GitHub Actions) runs the server tests and a client build on every push/PR.
Contributions are welcome — especially device template corrections and additions. To add or fix templates, edit server/db/seeds.js (the seedTemplates array) and open a PR. Each template lists its make, model, SKU, device type, rack height, and a default_ports array.
- Fork and create a branch.
- Make your change; run
npm run buildto confirm the client compiles. - For schema changes, keep
server/db/init.jsmigrations additive and idempotent. - Open a pull request.
MIT © 2026 breed007
CableMap was designed for documenting your own network. It supports multiple accounts (admin/editor/viewer) and API tokens, but is still intended to run on a trusted LAN or behind a reverse proxy with HTTPS — not exposed directly to the public internet. Set
COOKIE_SECURE=truebehind HTTPS, and changeADMIN_PASSWORD/SESSION_SECRETfrom their defaults.


