npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chromux

v0.2.0

Published

tmux for Chrome tabs — zero-dependency parallel Chrome tab controller via raw CDP

Readme

chromux

tmux for Chrome tabs — zero-dependency parallel Chrome tab controller via raw CDP.

Why

AI agents need to browse the web in parallel using the user's real Chrome (with logins preserved, no bot detection). Existing tools either bundle their own Chromium (Playwright/Puppeteer) or can't isolate tabs properly (agent-browser --cdp --session).

chromux solves this by talking to Chrome's DevTools Protocol directly using only Node.js built-ins — no Playwright, no Puppeteer, no npm dependencies.

| | Playwright/Puppeteer | agent-browser --cdp | chromux | |---|---|---|---| | Browser | Bundled Chromium | Real Chrome | Real Chrome | | Bot detection | Often caught | Avoided | Avoided | | Tab isolation | Yes | No (sessions share tab) | Yes | | Parallel agents | Yes | Broken | Yes | | Dependencies | 100s of MB | playwright-core | None | | Profile management | No | No | Yes |

Prerequisites

  • Node.js >= 22 (for built-in WebSocket)
  • Google Chrome installed

Quick Start

# Launch Chrome with an isolated profile (auto-finds Chrome, auto-assigns port)
chromux launch

# Open tabs for two agents
chromux open agent-a https://news.ycombinator.com
chromux open agent-b https://reddit.com/r/programming

# Each operates independently
chromux snapshot agent-a
chromux click agent-a @3
chromux eval agent-b "document.title"
chromux screenshot agent-a /tmp/hn.png

# Clean up
chromux close agent-a
chromux close agent-b
chromux kill default

Profile Management

Each profile is an isolated Chrome instance with its own user-data-dir, logins, cookies, and extensions.

# Launch named profiles
chromux launch work
chromux launch personal

# See what's running
chromux ps
# PROFILE             PORT    PID       STATUS      TABS
# work                9300    12345     running     3
# personal            9301    12346     running     1

# Use a specific profile for tab commands
chromux --profile work open my-tab https://...
CHROMUX_PROFILE=personal chromux open other-tab https://...

# Default profile is "default" — used when no --profile specified
chromux open my-tab https://...  # → uses "default" profile (auto-launches if needed)

# Stop a profile
chromux kill work

Commands

Profile

| Command | Description | |---------|-------------| | launch [name] | Launch Chrome with isolated profile (default: "default") | | launch <name> --port N | Launch with specific port | | ps | List running profiles | | kill <name> | Stop profile (Chrome + daemon) |

Tab Operations

| Command | Description | |---------|-------------| | open <session> <url> | Navigate (auto-creates tab) | | snapshot <session> | Accessibility tree with @ref numbers | | click <session> @<ref> | Click element by ref | | click <session> "selector" | Click by CSS selector | | fill <session> @<ref> "text" | Fill input field | | type <session> "text" | Keyboard input (Enter, Tab, etc.) | | eval <session> "js" | Run JavaScript expression | | screenshot <session> [path] | Take PNG screenshot | | scroll <session> up\|down | Scroll page | | wait <session> <ms> | Wait milliseconds | | close <session> | Close tab | | list | List active sessions in current profile | | stop | Stop daemon (keeps Chrome running) |

Architecture

~/.chromux/
  config.json                    Global config (optional)
  profiles/
    default/                     Chrome user-data-dir
      .state                     PID, port, socket path
    work/
      .state

Chrome instance A (port 9300, ~/.chromux/profiles/default/)
  ↑ CDP WebSocket per tab
chromux daemon (Unix socket /tmp/chromux-default.sock)
  ↑ HTTP
CLI / AI agents

Chrome instance B (port 9301, ~/.chromux/profiles/work/)
  ↑ CDP WebSocket per tab
chromux daemon (Unix socket /tmp/chromux-work.sock)
  ↑ HTTP
CLI / AI agents
  • No Playwright/Puppeteer — raw WebSocket + http from Node.js stdlib
  • Tab CRUD via Chrome's /json/* HTTP endpoints
  • Page ops via CDP WebSocket JSON-RPC
  • Daemon per profile keeps WebSocket connections alive across CLI invocations
  • Auto-launchchromux open auto-launches default profile if needed

Configuration

Optional ~/.chromux/config.json:

{
  "chromePath": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
  "portRangeStart": 9300,
  "portRangeEnd": 9399
}

Environment

| Variable | Default | Description | |----------|---------|-------------| | CHROMUX_PROFILE | default | Active profile name |

License

MIT