πŸš€ Big News:Socket Has Acquired Secure Annex.Learn More β†’
Socket
Book a DemoSign in
Socket

@romanmatena/browsermonitor

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@romanmatena/browsermonitor

Browser console, network, DOM monitoring for debugging and LLM workflows. Captures console, network, cookies, screenshot, DOM. HTTP API for LLM/scripts. WSL+Windows, Linux, Open/Join modes.

latest
Source
npmnpm
Version
2.1.1
Version published
Weekly downloads
9
200%
Maintainers
1
Weekly downloads
Β 
Created
Source

Browser Monitor

Browser Monitor

CI npm npm downloads Node License GitHub PRs Welcome

Browser console, network, DOM, and screenshot monitoring for debugging and LLM workflows.

npm Β· GitHub

Installation Β· Quick Start Β· HTTP API Β· Contributing

What it is: Browser Monitor lets you capture the live state of a browserβ€”console output, network requests, cookies, screenshot, and the current page DOMβ€”and write it all to files. You (or an LLM agent) can then read those files instead of asking someone to copy-paste from DevTools or the browser.

Why it's useful: When debugging a frontend app or feeding context to an AI assistant, you need the real console, the real DOM, and the real network traffic. Manual copy-paste is slow and error-prone. This tool connects to Chrome via Puppeteer, records everything in one place, and exposes a simple "dump" so the next step is always "read the files" instead of "please open the browser and copy this."

Who needs it: Frontend and full-stack developers who debug in the browser; teams using LLM coding agents that need up-to-date DOM and network data; anyone who wants a repeatable way to snapshot browser state for logs, tests, or AI context. If you've ever asked a colleague to "send me what you see in the console" or "paste the HTML of that element," you need this. Without it, getting a reliable, one-command snapshot of the live browser is much harder.

Entry point: browsermonitor (global CLI). Run it in any project directory.

Features

  • Console, network, DOM, cookies, screenshot – capture full browser state in one dump
  • Screenshot – each dump writes .browsermonitor/.puppeteer/screenshot.png (current tab viewport); ideal for LLM vision or quick visual checks
  • HTTP REST API – trigger dump, status, clear, tab switch via curl (ideal for LLM agents)
  • Multiple modes – Interactive (menu), Open (launch Chrome), Join (attach to existing)
  • WSL + Windows – Chrome on Windows, app in WSL with automatic port proxy
  • Native Linux – run with GUI on Ubuntu or headless
  • Lazy or realtime – buffer in memory or write logs immediately

Screenshots (demo)

Interactive modeOpen mode / Dump output
InteractiveOutput

Installation

Install globally from npm:

# Using npm
npm install -g @romanmatena/browsermonitor

# Or pnpm
pnpm add -g @romanmatena/browsermonitor

Note: Chromium download is skipped β€” browsermonitor uses your system Chrome/Chromium. No extra 300 MB download.

First run (interactive): When you run browsermonitor for the first time in a project directory, interactive mode asks for HTTP API port, saves settings.json, and updates agent files (CLAUDE.md, AGENTS.md, memory.md). When you press o (open), it asks for the default URL.

Re-init: Run browsermonitor init to recreate settings and update agent files.

Quick Start

browsermonitor                    # Interactive: menu β†’ o (open) or j (join)
browsermonitor --open             # Open mode: launch new Chrome and monitor
browsermonitor --join=9222        # Join mode: attach to existing Chrome on port 9222

Modes

ModeHow to runWhen to use
Interactivebrowsermonitor (no flags)First run asks HTTP port. Then menu: o = open Chrome (asks URL on first use), j = join running Chrome, q = quit.
Openbrowsermonitor --open [url]Launch a new Chrome and monitor it. Uses current dir for logs.
Joinbrowsermonitor --join=PORTAttach to an existing Chrome with remote debugging on PORT (e.g. 9222). Port is required.

Windows (native)

When to use: You develop directly on Windows using IIS, XAMPP, or other local server.

cd C:\Projects\my-app
browsermonitor --open https://localhost:5173/

Open mode launches Chrome via Puppeteer. No port proxy or firewall setup needed.

Windows + WSL

When to use: Your app runs in WSL (Node.js, Python, etc.) but you want Chrome on Windows for GPU/WebGL.

Usage: Run from WSL:

cd /srv/project
browsermonitor --open https://localhost:5173/

How it works: Open mode detects WSL and launches Chrome Canary on Windows, sets up port proxy (0.0.0.0:9222 β†’ Chrome), and connects from WSL via the Windows gateway IP. Port proxy requires Administrator (one-time) on first run.

Join mode (attach to existing Chrome): Start Chrome manually with --remote-debugging-port=9222, then browsermonitor --join=9222 from WSL. For port proxy, run in PowerShell (Admin): netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1

Linux (Ubuntu) with GUI

When to use: You develop on native Linux (Ubuntu, etc.) with a display. Chrome/Chromium runs with GUI on the same machine.

browsermonitor --open https://localhost:5173/

Chrome/Chromium is started via Puppeteer with --remote-debugging-port. No port proxy needed; direct localhost connection.

Requirements:

  • Chrome or Chromium installed: apt install chromium-browser or install Google Chrome
  • Display available (X11 or Wayland)

For join mode (attach to existing Chrome): start Chrome manually with --remote-debugging-port=9222, then browsermonitor --join=9222.

Chrome Profile

Each project gets its own Chrome profile:

  • WSL: %LOCALAPPDATA%\browsermonitor\{project}_{hash} (Windows path)
  • Native: .browsermonitor/.chrome-profile/ in project dir

Separate cookies and logins per project; won't interfere with your regular Chrome.

Chrome Canary (Required)

browsermonitor requires Chrome Canary for launching Chrome (--open and --join when no Chrome is running). Regular Chrome cannot be used because Chrome is a singleton β€” all instances bind to the first launched process. If your regular Chrome is already open, a new Chrome with --remote-debugging-port would just open a window in the existing process and the debug port would be ignored.

Chrome Canary runs as a completely separate process from regular Chrome (different singleton, different profile directory), so:

  • Your regular Chrome stays completely untouched
  • Debug port is guaranteed to work
  • No singleton hijacking issues

Installation:

Note: If you already have Chrome running with --remote-debugging-port (e.g. started manually), you can connect to it with browsermonitor --join=PORT regardless of whether it's Canary or regular Chrome.

Project Directory Structure

When browsermonitor runs in a project directory, it creates:

<project-root>/
β”œβ”€β”€ .browsermonitor/
β”‚   β”œβ”€β”€ settings.json          # Project config (defaultUrl, httpPort, etc.)
β”‚   β”œβ”€β”€ browsermonitor.pid     # PID file for recovery
β”‚   └── .puppeteer/            # All dump outputs
β”‚       β”œβ”€β”€ console.log
β”‚       β”œβ”€β”€ network.log
β”‚       β”œβ”€β”€ network-log/       # Per-request JSON files
β”‚       β”œβ”€β”€ cookies/           # Per-domain cookie JSONs
β”‚       β”œβ”€β”€ dom.html
β”‚       └── screenshot.png
β”‚   └── .chrome-profile/       # Chrome profile (native) or
β”‚                              # %LOCALAPPDATA%\browsermonitor\ (WSL)

Keyboard Controls (open/join mode)

KeyAction
dDump logs, cookies, screenshot, and current page HTML to files
cClear in-memory buffer
sShow status (buffer counts, URLs)
pPause/resume recording (stop/start collecting)
tSwitch monitored tab
hFull help (incl. LLM instructions and HTTP API)
kKill Chrome and exit [open] / kill Chrome and quit [join]
qQuit (Chrome stays open) [open] / disconnect only [join]

Output Files

FileDescription
.browsermonitor/.puppeteer/console.logConsole output
.browsermonitor/.puppeteer/network.logNetwork requests
.browsermonitor/.puppeteer/network-log/Detailed request/response JSON
.browsermonitor/.puppeteer/cookies/Cookies per domain
.browsermonitor/.puppeteer/dom.htmlCurrent page HTML (JS-modified element tree). LLM: read this for the live DOM structure.
.browsermonitor/.puppeteer/screenshot.pngScreenshot of the current tab viewport (PNG). Written on each dump.

All files are written on dump (key d or curl …/dump).

HTTP API

Use curl to communicate with the HTTP API over REST. Default URL: http://localhost:60001.

EndpointDescription
GET /dumpDump logs, DOM, cookies, screenshot to files; returns output file paths
GET /statusCurrent state: status, mode, monitored URLs, collecting flag, stats
GET /stopPause collecting (console/network)
GET /startResume collecting
GET /clearClear in-memory buffers
GET /tabsList all user tabs (index, url)
GET /tab?index=NSwitch monitored tab (1-based index)
GET /computed-styles?selector=...Get computed CSS for first element matching selector (default: body)
POST /puppeteerCall Puppeteer page method. Body: { "method": "page.goto", "args": ["https://..."] }

Puppeteer whitelist: content, click, focus, goto, hover, pdf, screenshot, select, setDefaultNavigationTimeout, setDefaultTimeout, setViewport, title, type, url, waitForSelector, waitForTimeout

curl http://localhost:60001/dump       # Dump to files
curl http://localhost:60001/status     # Check status
curl http://localhost:60001/clear      # Clear buffers
curl http://localhost:60001/tabs       # List tabs
curl "http://localhost:60001/tab?index=2"  # Switch to tab 2
curl "http://localhost:60001/computed-styles?selector=.my-class"  # Get computed CSS
curl -X POST http://localhost:60001/puppeteer -H "Content-Type: application/json" \
  -d '{"method":"page.goto","args":["https://example.com"]}'  # Navigate via API

CLI Options

OptionDescription
--openGo directly to open mode (launch new Chrome)
--join=PORTGo directly to join mode; attach to Chrome at PORT (port required)
--port=PORTHTTP API port (default: from settings or 60001)
--headlessRun Chrome without GUI
--realtimeWrite logs immediately (default: lazy buffer)
--timeout=MSHard timeout in ms; process exits after (0 = disabled)
--nav-timeout=MSNavigation timeout in ms (default: from settings, 0 = no limit)

Config (.browsermonitor/settings.json): defaultUrl, headless, navigationTimeout, ignorePatterns, httpPort, realtime

Troubleshooting WSL

Connection refused from WSL

  • Verify Chrome is listening:

    netstat -ano | findstr "127.0.0.1:9222.*LISTEN"
    
  • Verify port proxy:

    netsh interface portproxy show v4tov4 | findstr 9222
    

    Should show: 0.0.0.0 9222 127.0.0.1 9222

  • Test from WSL:

    curl -s http://$(ip route | grep default | awk '{print $3}'):9222/json/version
    

Chrome won't start with debug port

Port proxy blocks port 9222 during Chrome startup. Open mode handles this automatically; if it fails, run PowerShell as Administrator so the port proxy can be configured.

Manual reset

# 1. Remove port proxy (both types)
netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=0.0.0.0
netsh interface portproxy delete v4tov6 listenport=9222 listenaddress=0.0.0.0

# 2. Kill ONLY browsermonitor Chrome (NOT your regular browser!)
Get-WmiObject Win32_Process -Filter "name='chrome.exe'" | Where-Object { $_.CommandLine -match 'browsermonitor' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }

# 3. Start Chrome Canary (recommended - isolated from regular Chrome)
Start-Process "$env:LOCALAPPDATA\Google\Chrome SxS\Application\chrome.exe" -ArgumentList "--remote-debugging-port=9222","--user-data-dir=$env:LOCALAPPDATA\browsermonitor\manual"

# 4. Wait 5s, check binding, add appropriate proxy
Start-Sleep 5
# Check if IPv4 or IPv6:
netstat -ano | findstr "9222.*LISTEN"
# If 127.0.0.1:9222:
netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1
# If [::1]:9222:
netsh interface portproxy add v4tov6 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=::1

WARNING: Never use Stop-Process -Name chrome -Force - it kills ALL Chrome including your personal browser!

For Developers: WSL→Windows Chrome Internals

This section documents the technical details of connecting to Chrome from WSL2 when Chrome runs on Windows.

WSL2 Network Architecture

WSL2 runs in a lightweight Hyper-V virtual machine with its own network stack:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Windows Host                                            β”‚
β”‚   Chrome: 127.0.0.1:9222 (localhost only by default)    β”‚
β”‚                                                         β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚ WSL2 VM (e.g., 172.29.100.50)                   β”‚   β”‚
β”‚   β”‚                                                 β”‚   β”‚
β”‚   β”‚   browsermonitor trying to connect...           β”‚   β”‚
β”‚   β”‚   β†’ 127.0.0.1:9222 ❌ (WSL's own localhost)     β”‚   β”‚
β”‚   β”‚   β†’ 172.29.96.1:9222 βœ… (Windows gateway)       β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key insight: localhost in WSL2 refers to WSL's own network, not Windows. To reach Windows services, WSL must connect via the Windows gateway IP (typically 172.x.x.1).

Chrome Singleton Behavior

Chrome uses a singleton pattern - only one instance runs per user profile:

First launch:  chrome.exe --remote-debugging-port=9222 --user-data-dir=X
               β†’ Starts Chrome, listens on port 9222 βœ…

Second launch: chrome.exe --remote-debugging-port=9223 --user-data-dir=Y
               β†’ If Chrome is already running, the new process:
                 1. Sends command to existing Chrome via IPC
                 2. Opens new window in EXISTING process
                 3. New process exits immediately
                 4. --remote-debugging-port=9223 is IGNORED! ❌

Consequence: If user has Chrome open for regular browsing, launching a new Chrome with debug flags does nothing - the existing Chrome (without debugging) handles it.

Detection method (used in open-mode.mjs):

# From WSL, query Windows WMI for Chrome processes:
wmic.exe process where "name='chrome.exe'" get processid,commandline

# Parse output to find --remote-debugging-port=XXXX
# Multiple subprocesses report same port - deduplicate with Set

Remote Debugging Address Binding

Important: Chrome M113+ Security Change

Since Chrome M113 (May 2023), Chrome ignores the --remote-debugging-address=0.0.0.0 flag for security reasons. Chrome always binds to 127.0.0.1 only.

Sources:

FlagBindingAccessible from
--remote-debugging-port=9222127.0.0.1:9222Windows localhost only
--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0127.0.0.1:9222IGNORED since Chrome M113

For WSL access, port proxy is REQUIRED - there is no way to make Chrome bind to 0.0.0.0.

Port Proxy Mechanism

Windows netsh port proxy forwards connections from one address to another.

IPv4 vs IPv6 Binding:

Chrome may bind to either IPv4 (127.0.0.1) or IPv6 ([::1]) depending on system configuration. The monitor automatically detects which address Chrome uses and configures the appropriate proxy type:

Chrome Binds ToProxy TypeCommand
127.0.0.1:9222v4tov4netsh interface portproxy add v4tov4 ... connectaddress=127.0.0.1
[::1]:9222v4tov6netsh interface portproxy add v4tov6 ... connectaddress=::1

Detection logic (used in open mode):

// Check netstat output for Chrome's binding
const netstatOutput = execSync('netstat.exe -ano', { encoding: 'utf8' });
const lines = netstatOutput.split('\n').filter(l => l.includes(':9222') && l.includes('LISTEN'));
// Parse for 127.0.0.1:9222 or [::1]:9222

Manual proxy commands:

# IPv4 proxy: forward 0.0.0.0:9222 β†’ 127.0.0.1:9222
netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1

# IPv6 proxy: forward 0.0.0.0:9222 β†’ [::1]:9222
netsh interface portproxy add v4tov6 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=::1

# List existing proxies (check both types!)
netsh interface portproxy show v4tov4
netsh interface portproxy show v4tov6

# Remove proxy
netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=0.0.0.0
netsh interface portproxy delete v4tov6 listenport=9222 listenaddress=0.0.0.0

How it works:

WSL (172.29.100.50) β†’ Windows gateway (172.29.96.1:9222)
                              ↓ port proxy (v4tov4 or v4tov6)
                      Windows (127.0.0.1:9222 or [::1]:9222)
                              ↓
                      Chrome DevTools Protocol

Important: Port proxy requires Administrator privileges to configure.

Windows Firewall

Inbound connections to port 9222 require a firewall rule that allows WSL subnet:

# Check existing rules
Get-NetFirewallRule -DisplayName "*Chrome*" | Get-NetFirewallPortFilter

# Add rule with WSL subnet (one-time, persists across reboots)
# 172.16.0.0/12 covers the WSL2 dynamic IP range
New-NetFirewallRule -DisplayName "Chrome Debug (browsermonitor)" -Direction Inbound -LocalPort 9222-9299 -Protocol TCP -Action Allow -RemoteAddress LocalSubnet,172.16.0.0/12

# Update existing rule if it doesn't include WSL subnet
Set-NetFirewallRule -DisplayName "Chrome Remote Debugging" -RemoteAddress LocalSubnet,172.16.0.0/12

Note: If firewall rule exists but connections still timeout, check that RemoteAddress includes the WSL subnet (172.x.x.x range).

The 7-Step Diagnostic Process

The runWslDiagnostics() function performs:

StepCheckMethod
1Chrome instances on Windowswmic.exe process where "name='chrome.exe'"
2Network bindingsnetstat.exe -ano | findstr 9222
3Port configurationParse --remote-debugging-port (note: --remote-debugging-address is ignored since Chrome M113)
4Windows Firewallnetsh.exe advfirewall firewall show rule name=all
5Port proxy confignetsh.exe interface portproxy show v4tov4
6Scan port rangeCheck 9222-9299 for existing proxies
7Connectivity testfetch('http://gateway:port/json/version')

Automatic Chrome Detection Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ browsermonitor --join=9222                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Detect Windows gateway IP     β”‚
              β”‚ (ip route | grep default)     β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Try connect to gateway:9222   β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                   β”‚
                 Success              Fail
                    β”‚                   β”‚
                    β–Ό                   β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Connected β”‚    β”‚ Run diagnostics   β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚
                                        β–Ό
                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                               β”‚ Chrome running    β”‚
                               β”‚ with debug port?  β”‚
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚                   β”‚
                             Yes                 No
                              β”‚                   β”‚
                              β–Ό                   β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚ Offer port proxy β”‚  β”‚ Show how to      β”‚
                    β”‚ setup (admin)    β”‚  β”‚ start Chrome     β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Common Issues and Solutions

SymptomCauseSolution
Connection refusedChrome binds to 127.0.0.1 onlySet up port proxy
Connection timeoutChrome binds to IPv6 ([::1]) but proxy forwards to IPv4Use v4tov6 proxy instead of v4tov4
New Chrome ignores debug flagsSingleton joined existing processClose all Chrome windows first, or use port proxy to existing debug port
Port proxy won't startChrome already listening on 0.0.0.0Remove proxy, start Chrome, re-add proxy
"Access denied" from WSLFirewall blockingAdd inbound rule for port 9222

IPv6 Troubleshooting:

If connection times out after Chrome starts, check what address Chrome is listening on:

# Check Chrome's binding
netstat -ano | findstr "9222.*LISTEN"

# If you see [::1]:9222 (IPv6), you need v4tov6 proxy:
netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=0.0.0.0
netsh interface portproxy add v4tov6 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=::1

# If you see 127.0.0.1:9222 (IPv4), use v4tov4 proxy:
netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1

Environment Detection

The monitor detects WSL environment via:

const isWsl = process.platform === 'linux' &&
  (process.env.WSL_DISTRO_NAME ||
   fs.existsSync('/proc/sys/fs/binfmt_misc/WSLInterop'));

Debugging Tips

# From WSL: Get Windows gateway IP
ip route | grep default | awk '{print $3}'
# Result: 172.29.96.1

# From WSL: Test Chrome DevTools endpoint
curl -s http://172.29.96.1:9222/json/version | jq

# From WSL: Query Windows processes
wmic.exe process where "name='chrome.exe'" get processid,commandline

# From WSL: Check Windows netstat
netstat.exe -ano | grep 9222

# From Windows: Check what's listening
netstat -ano | findstr "9222.*LISTEN"

Code References

Keywords

browser

FAQs

Package last updated on 07 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts