Installation
Requirements, running from source, and the macOS desktop app.
Traffic Jam runs two ways: the web app from source (Vite frontend + Go API), or the packaged macOS arm64 Electron desktop app that embeds and manages the Go backend for you.
Requirements
| Dependency | Needed for |
|---|---|
| Node.js and npm | Frontend toolchain, dev server, Electron packaging |
| Go | Building and running the API backend (go run ./server) |
mitmdump on PATH | Live capture |
tshark on PATH | Live packet capture only |
The backend parses pcap/pcapng in-process with gopacket and decrypts supported TLS 1.2/1.3 sessions from NSS keylog files or pcapng Decryption Secrets Blocks. TShark is not required to import captures — only the optional live packet-capture workflow uses it (see /docs/en/capture/). Parsed sessions persist in SQLite, so imported sessions survive API restarts.
Run the web app from source
Start the API, then the frontend, in two terminals:
npm ci # or: make install
npm run dev:api # go run ./server — listens on 127.0.0.1:8790
npm run dev:web # Vite dev server; proxies /api to http://127.0.0.1:8790
The standalone development API accepts requests without a capability token by default, but only browser origins on loopback addresses (localhost, 127.0.0.1, ::1) and the desktop origin (traffic-jam://app) are allowed; any other Origin is rejected with HTTP 403.
To require a token, set TRAFFIC_JAM_API_TOKEN for the API and start the frontend with the same value as VITE_TRAFFIC_JAM_API_TOKEN. API clients send the token in the X-Traffic-Jam-Token header. Additional exact origins can be allowlisted with the comma-separated TRAFFIC_JAM_ALLOWED_ORIGINS value.
Storage and environment variables
| Variable | Default | Purpose |
|---|---|---|
TRAFFIC_JAM_ADDR | 127.0.0.1:8790 | Backend listen address |
TRAFFIC_JAM_DB_PATH | .traffic-jam/traffic-jam-v2.sqlite3 | SQLite database file |
TRAFFIC_JAM_CAPTURE_DIR | .traffic-jam/live-captures (or beside the configured database in desktop builds) | Live-capture artifact directory |
TRAFFIC_JAM_API_TOKEN | unset (dev API is token-less) | Capability token required by the API |
VITE_TRAFFIC_JAM_API_TOKEN | unset | Same token, read by the web frontend at build/dev time |
TRAFFIC_JAM_ALLOWED_ORIGINS | unset | Comma-separated extra allowed browser origins |
macOS arm64 desktop app
The Electron shell starts the Go API on a free 127.0.0.1 port, generates a cryptographically random capability token on every launch, and passes both only to its backend and to the renderer through the isolated preload bridge (contextIsolation: true, nodeIntegration: false). The backend binary is bundled as an extra resource; in development the shell uses dist-electron/backend/traffic-jam-api if present and falls back to go run ./server. The packaged app augments PATH with the login shell’s PATH plus common Homebrew locations such as /opt/homebrew/bin, so mitmdump installed via Homebrew is found without extra configuration. The SQLite database lives in the app’s user data directory (traffic-jam-v2.sqlite3).
Run it locally (builds the frontend and the macOS arm64 backend, then launches Electron):
npm run desktop:dev
Packaging and release
make pack # or: npm run desktop:pack — unpacked .app in release/mac-arm64/
make dist # or: npm run desktop:dist — DMG, ad-hoc codesigned for local use
make release-signed SIGN_IDENTITY='Developer ID Application: Your Name (TEAMID)'
make version VERSION=1.2.3 # set package.json version before packaging
make dist produces an ad-hoc signed DMG (electron-builder identity: null plus an ad-hoc afterPack script) suitable for local use; make release-signed requires a valid Developer ID certificate in your keychain and fails fast if SIGN_IDENTITY is empty. All desktop artifacts are written to release/.
[!NOTE] Ad-hoc signed apps trigger a Gatekeeper warning on other machines. Distribute the Developer ID–signed DMG from
make release-signedfor anyone else’s use.
Makefile targets
| Target | Description |
|---|---|
make install | npm ci |
make check | Lint + logic tests + Go tests |
make check-ui | make check + rendered UI and axe tests |
make test-e2e | Isolated Playwright browser smoke |
make test-electron | Isolated macOS arm64 Electron launch smoke |
make build-all | Frontend + macOS arm64 backend |
make pack | Unpacked .app |
make dist | DMG (ad-hoc codesign) |
make release-signed | DMG with Developer ID signing (SIGN_IDENTITY=…) |
make clean | Remove dist, dist-electron, release, and Playwright output directories |
[!TIP] A typical local verification flow is
make install check build-allbeforemake packormake dist. Browser tests install Chromium once vianpx playwright install chromium; both browser and Electron tests use isolated databases and user-data directories, so they never touch normal developer state.
[!WARNING] Traffic Jam is for authorized testing of systems you have permission to test. Replay, mutation probes, and JWT test-token generation (including
alg=noneand RS-to-HS tokens) send real requests — point them only at targets you are authorized to assess.