CLI & Configuration

Environment variables, storage locations, and API security settings.

Traffic Jam has no config file. The Go backend reads environment variables at startup, the Electron shell sets them for you, and the web frontend picks up one build-time variable. This page lists every knob, where data lives on disk, and how the local API is protected.

Run the dev stack

npm run dev:api    # go run ./server — backend on 127.0.0.1:8790
npm run dev:web    # Vite dev server, proxies /api to http://127.0.0.1:8790
npm run desktop:dev # build frontend + macOS arm64 backend, launch Electron

See /docs/en/getting-started/installation/ for prerequisites (mitmdump for live capture, tshark only for live packet capture — importing pcap/pcapng/HAR needs neither).

Environment variables

Backend variables, read once at process start:

VariableDefaultEffect
TRAFFIC_JAM_ADDR127.0.0.1:8790Listen address of the API.
TRAFFIC_JAM_DB_PATH.traffic-jam/traffic-jam-v2.sqlite3SQLite database file (sessions, investigations, decode scripts, profiles).
TRAFFIC_JAM_CAPTURE_DIR.traffic-jam/live-capturesLive-capture artifact directory. If unset and TRAFFIC_JAM_DB_PATH is set, defaults to live-captures beside the database file.
TRAFFIC_JAM_API_TOKEN(empty)Capability token. Empty = token not required; set = every request must carry it (see below).
TRAFFIC_JAM_ALLOWED_ORIGINS(empty)Comma-separated list of additional exact browser Origin values to accept.
TRAFFIC_JAM_MAX_UPLOAD_BYTES4294967296 (4 GiB)Maximum capture upload size in bytes.

Frontend and desktop variables:

VariableWhereEffect
VITE_TRAFFIC_JAM_API_TOKENVite build/devCapability token the web client sends when the desktop bridge is absent.
TRAFFIC_JAM_USER_DATA_DIRElectronOverrides the user-data directory (used by the Electron smoke test for isolation).
TRAFFIC_JAM_DEBUG_MENUElectron1 adds Inspect Element / DevTools to the packaged app’s menus.

Example — token-protected dev session:

TRAFFIC_JAM_API_TOKEN=s3cret npm run dev:api
VITE_TRAFFIC_JAM_API_TOKEN=s3cret npm run dev:web

Storage locations

LocationContents
.traffic-jam/traffic-jam-v2.sqlite3Dev-server database (relative to the backend’s working directory).
.traffic-jam/live-captures/Live-capture artifacts (see /docs/en/capture/live-capture/).
<userData>/traffic-jam-v2.sqlite3Desktop database in Electron’s user-data directory; live-capture artifacts are stored beside it. Open it via Capture → Open Traffic Jam Data Folder.

Parsed capture sessions persist in SQLite, so imported sessions survive API restarts.

API security model

Every /api/* request passes one middleware that enforces two independent checks.

Origin allowlist. A request with an Origin header is accepted only if the origin is:

  • an exact entry in TRAFFIC_JAM_ALLOWED_ORIGINS;
  • the desktop origin traffic-jam://app; or
  • an http/https origin whose host is localhost or a loopback IP (127.0.0.1, ::1).

Any other origin is rejected with HTTP 403 origin is not allowed. Requests without an Origin header (curl, Go clients) skip this check.

Capability token. If TRAFFIC_JAM_API_TOKEN is set, the request must carry the same value in the X-Traffic-Jam-Token header, compared in constant time; a missing or wrong token yields HTTP 401 invalid API capability token. If the variable is empty, no token is required.

curl -H "X-Traffic-Jam-Token: $TOKEN" http://127.0.0.1:8790/api/health

The web client sends the token automatically (from the desktop bridge, falling back to VITE_TRAFFIC_JAM_API_TOKEN).

[!WARNING] The dev API with no token still trusts any process on your machine that can reach loopback. Set TRAFFIC_JAM_API_TOKEN whenever the backend runs alongside untrusted local software, and never bind TRAFFIC_JAM_ADDR to a non-loopback interface.

Dev vs desktop differences

Dev (npm run dev:api)Desktop (Electron)
Portfixed 127.0.0.1:8790free 127.0.0.1 port chosen at launch
Tokennone unless you set TRAFFIC_JAM_API_TOKEN32-byte cryptographically random token generated every launch
Token deliveryVITE_TRAFFIC_JAM_API_TOKEN at build timepassed to the renderer through the isolated preload bridge only (contextIsolation: true, nodeIntegration: false)
Database.traffic-jam/traffic-jam-v2.sqlite3<userData>/traffic-jam-v2.sqlite3
FrontendVite dev serverserved from traffic-jam://app
PATHyour shell’saugmented with your login shell’s PATH plus Homebrew and user-bin directories (/opt/homebrew/bin, ~/.local/bin, ~/go/bin, …) so mitmdump, tshark, adb, and frida resolve from a GUI launch

Checks and tests

CommandWhat it runs
npm run lintESLint over the frontend and Electron code.
npm testLogic tests (Vitest, Node environment).
npm run test:uiReact Testing Library + axe accessibility tests in jsdom.
npm run test:e2ePlaywright Chromium smoke against testdata/browser-smoke.har; uses a temporary SQLite database and capture directory.
npm run test:electronBuilds frontend + backend, launches Electron with an isolated user-data directory.
go test ./server/...Backend unit tests.
make checklint + npm test + go test ./server/....
make check-uimake check + rendered UI tests.

[!NOTE] Browser tests need Chromium once: npx playwright install chromium. Both e2e and Electron tests point the database, capture directory, and user-data directory at temporary paths, so they never touch your normal developer state.

Replay, batch limits, and the request workbench are covered in /docs/en/replay/workbench/; decode-script plugins in /docs/en/collector/decode-scripts/.

Traffic Jam documentation. Built with Hugo.