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

devtools-server

v0.0.2

Published

Runs a simple server that allows you to connect to Chrome DevTools from dynamic hosts, not only localhost.

Readme

devtools-server

Enables remote connection to DevTools of a Chrome browser running somewhere on the internet, typically in a Docker container.


                         container at some-host.com
                   |------------------------------------|
 |--------|        |  |----------|        |----------|  |
 | client | <====> |  | devtools |        |  Chrome  |  |
 |--------|        |  |  server  | <====> | DevTools |  |
                   |  |----------|        |----------|  |
                   |------------------------------------|

The client can not connect to Chrome DevTools directly due to security limitations of Chrome, which allows connections only from localhost. devtools-server bridges that connection and serves as a proxy between the client and the Chrome DevTools. Automatically forwarding connections to the first open tab, ignoring about:blank.

Example

const server = new DevToolsServer({
    containerHost: 'some-host.com',
    devToolsServerPort: 4321,
});

await server.start();

Server will now accept connections at https://some-host.com and make DevTools frontend available there.

Use with Puppeteer

const DevToolsServer = require('devtools-server');
const puppeteer = require('puppeteer');

async function main() {
    const browser = await puppeteer.launch({
        args: ['--remote-debugging-port=9222'],
    });

    const server = new DevToolsServer({
        // Using localhost here so you can run
        // the example on your local machine.
        containerHost: 'localhost:4321',
        devToolsServerPort: 4321,
        insecureConnection: true,
    });

    await server.start();

    const page = await browser.newPage();
    await page.goto('https://example.com');

    // Now connect to the server. You will see the page
    // loaded and DevTools open.

    // This delay is only here to give you enough time to
    // connect and inspect the page. See debugging section
    // below for breakpoint use.
    await page.waitFor(2 * 60 * 1000);

    server.stop();
    await browser.close();
}

main();

Debugging

Probably the most common use-case for DevTools is debugging. You can easily extend your scripts with debugging capabilities by enabling the Debugger and adding breakpoints.

// page is a Puppeteer Page
const cdpClient = await page.target().createCDPSession();
await cdpClient.send('Debugger.enable');

// adding breakpoints later

// Stops execution in the browser,
// but this script will keep running.
await cdpClient.send('Debugger.pause');

// Stops execution in both browser
// and this script. Will not continue
// until the execution is resumed in browser.
await page.evaluate(() => { debugger; });

Use with Apify

This library was created to be used with the Apify platform to enable its users viewing and debugging their scrapers directly in the application UI.

To access the containers running on the platform, one needs to utilize the CONTAINER_URL and CONTAINER_PORT environment variables. If you want a better understanding of this library, read how to run a web server.

const browser = await Apify.launchPuppeteer({
    args: ['--remote-debugging-port=9222'],
})

const server = new DevToolsServer({
    containerHost: process.env.CONTAINER_URL,
    devToolsServerPort: process.env.CONTAINER_PORT,
});

await server.start();

Everything else is the same as in the Puppeteer examples.

Using with PuppeteerCrawler

Here it gets a bit tricky because the crawler will open and close pages on its own. Depending on your use-case, you'll have to do one or all of those things:

  • set maxConcurrency to 1 to only use a single tab. Otherwise it gets messy
  • prevent retiring of browsers by setting retireInstanceAfterRequestCount high.
  • increase handlePageTimeoutSecs to prevent timeouts killing your pages
  • increase gotoTimeoutSecs if you use breakpoints before navigation
  • add delays and timeouts inside the handlePageFunction to slow things down You can use page.waitFor(millis) to create a delay
  • add breakpoints using await page.evaluate(() => { debugger; }) to stop execution

Example constructor options

const puppeteerCrawlerOptions = {
    ...otherOptions, // such as requestQueue, handlePageFunction...
    maxConcurrency: 1,
    handlePageTimeoutSecs: 3600, // 1 hour
    gotoTimeoutSecs: 3600,
    launchPuppeteerOptions: {
        args: ['--remote-debugging-port=9222']
    },
    puppeteerPoolOptions: {
        retireInstanceAfterRequestCount: 10000
    }
}