Repository navigation
Getting Started
- Node.js: 22.12 or higher
- A Chromium-based browser: Chrome, Chromium or Microsoft Edge (latest stable recommended)
npm install -g browser-debugger-cli
bdg --versionbdg launches the installed Chrome by default. To use Microsoft Edge (or another Chromium-based browser), set CHROME_PATH to its binary:
CHROME_PATH="/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge" bdg example.com # macOS
CHROME_PATH=/usr/bin/microsoft-edge bdg example.com # LinuxOr start the browser yourself with --remote-debugging-port=9222 --user-data-dir=<dir> and attach with bdg example.com --chrome-ws-url 9222.
Edge is tested; Brave and Chromium should work the same way. Firefox and Safari are not supported: bdg uses the Chrome DevTools Protocol, which they do not implement.
| Platform | Status | Notes |
|---|---|---|
| macOS | Native | Full support |
| Linux | Native | Full support |
| Windows WSL | Supported | Run inside WSL |
| Docker | Supported | See docs/DOCKER.md in the repository |
| PowerShell | Not yet | Use WSL instead |
| Git Bash | Not yet | Use WSL instead |
The CLI talks to its session over a Unix domain socket. Windows users should run bdg inside WSL.
bdg example.comThis:
- Launches Chrome with the DevTools Protocol enabled (with a window on macOS, unless over SSH or
CIis set, and on Linux whenDISPLAY/WAYLAND_DISPLAYis set; headless otherwise; force with--headless/--no-headless) - Starts the background session that keeps the connection open
- Opens the URL and waits until the page has loaded
A URL that cannot be loaded at all (DNS failure, connection refused) fails with exit code 80. A page that answers with an HTTP error still starts the session and warns, e.g. ⚠ The page responded with HTTP 500.
Useful start options:
bdg localhost:3000 --port 9223 # Chrome debugging port
bdg localhost:3000 --stop-after 600 # Stop 600 s after the page has loaded
bdg https://localhost:5173 --chrome-flags="--ignore-certificate-errors"
bdg localhost:3000 --user-data-dir ~/.bdg-profile # Keep cookies/storage between sessions
bdg localhost:3000 --capture-all # Record tracking domains and all bodies
bdg localhost:3000 --viewport 1280x800 # Exact viewport for the whole session
bdg localhost:3000 --color-scheme dark # Emulate prefers-color-scheme
bdg localhost:3000 --session agent-1 # Named session (own Chrome and port)The start prints a few lines: the target, any notices, and the next commands to try:
Session Started
Target: https://example.com/
Next: bdg dom layout <selector>, bdg dom query <selector>, bdg dom form, bdg peek, bdg dom screenshot out.png
More: bdg --help (bdg --help --json for agents)
bdg dom query "button" # Find elements: [0], [1], ...
bdg dom get 0 # Semantic summary of match 0
bdg dom layout 0 # Where it is, visible or covered (no screenshot)
bdg dom fill 'input[name="q"]' "shoes" # Fill a field
bdg dom click 'button:has-text("Search")' # Click by visible text; reports Page:, New text:, requests
bdg dom wait ".results" --visible # Wait for results shown later
bdg page navigate example.com/about # Load another URL and wait
bdg eval "document.title" # Run JavaScript in the page
bdg dom screenshot page.png # Screenshot (sized for vision models)bdg peek # Last network requests and console messages
bdg network list # All captured requests (filters, presets)
bdg console # Errors and warnings of the current page
bdg peek --follow # Live view (Ctrl-C to quit)bdg cdp --list # All domains
bdg cdp Network --list # Methods in a domain
bdg cdp --search cookie # Search methods by keyword
bdg cdp Network.getCookies --describe # Parameters and return types
bdg cdp Runtime.evaluate --params '{"expression":"document.title","returnByValue":true}'bdg stopTelemetry lives in the session only: export what you need (e.g. bdg network har capture.har) before bdg stop.
bdg status # Page, PIDs, port, activity
bdg status --verbose # Also Chrome executable, mode and profile
bdg status --json # JSON envelope
bdg page info # Just the URL and title
bdg sessions # All sessions (default and named)Without a session, bdg status says so (exit 0) and, if the last session ended on its own, why: The last session ended at 7:37:41 PM: the --timeout was reached.
All other commands need a running session and exit with code 83 ("No active session") otherwise. Only bdg <url> starts one.
--session <name> (or BDG_SESSION) gives each agent or task its own daemon, Chrome, port and files in ~/.bdg/sessions/<name>/. Every command accepts it; bdg stop --session <name> stops only that one. See Commands.
bdg cleanup # Remove files left by a crashed session, close its orphaned Chrome
bdg cleanup --force # Kill a stuck session (daemon + its Chrome), then clean up
bdg cleanup --session a1 --purge # Also delete a named session's directorycleanup only touches bdg's own daemon and the Chrome it launched; it never kills other Chrome processes.
bdg <url> and bdg page navigate/reload/back/forward wait for the page to be ready:
- The browser's
loadevent fires - The network is quiet (200 ms without requests) and the DOM is quiet (300 ms without mutations)
If the document is still loading after that wait, the command still succeeds but warns (⚠ The page is still loading (document.readyState: loading); waiting on: …); use bdg dom wait --load or bdg dom wait <selector>.
page ... commands accept --no-wait to return at once. Interaction commands (dom click, fill, hover, press-key, scroll) wait for the requests the action starts (up to 2 s); they accept --no-wait too. For results a page shows later (timers, spinners), use bdg dom wait.
bdg stores session data in ~/.bdg/ (override with BDG_SESSION_DIR):
| File | Purpose |
|---|---|
daemon.sock |
Unix socket; a session is running if it accepts connections |
daemon.pid |
Daemon process ID (informational) |
session.meta.json |
Session metadata (Chrome PID, port, target) |
chrome.pid |
Chrome launched by bdg, kept until it is confirmed gone |
daemon.log |
Daemon output (rotated above 5 MB) |
last-session.json |
Why the last session ended (shown by bdg status) |
query-cache.json |
Element indices from the last dom query / dom form
|
port.txt |
CDP port reused by the next session |
chrome-profile/ |
Chrome user data (unless --user-data-dir) |
sessions/<name>/ |
Same files for each named session |
- Commands - Full command reference
- For AI Agents - Agent integration patterns
- Recipes - Common workflows