chrome-remote-interface is a free, open source browsers & extensions project written in JavaScript and released under MIT. It has 4,553 GitHub stars, 322 forks and 12 open issues, and was last pushed 7 months ago. On this registry it ranks #65 of 133 tracked projects in Browsers & Extensions, with 5 head-to-head comparisons available.

What is chrome-remote-interface?

chrome-remote-interface is an MIT-licensed JavaScript library that gives Node.js applications a straightforward API for the Chrome Debugging Protocol, so they can instrument Chrome and other protocol-compatible runtimes without handling raw protocol messages.

What it is

chrome-remote-interface is a Node.js package that speaks the Chrome Debugging Protocol. It exposes the protocol as JavaScript objects: a developer connects to a running browser or runtime, extracts the domains they care about, such as Network and Page, and calls their methods directly. Commands become awaited function calls and notifications become registered handlers, while the library manages the protocol connection itself. It is published on npm under the MIT licence, is written in JavaScript, and has 4,553 stars, 322 forks, and 12 open issues.

The problem it solves is the plumbing between a Node.js program and a debugging endpoint. Without it, scripting a browser means opening a protocol connection by hand, serialising commands, correlating responses, and routing incoming notifications to the right handler. It lives in the Node.js and npm ecosystem and targets any application implementing the Chrome Debugging Protocol, which the project has verified against Chrome, Opera, Node.js, Safari on iOS, Edge, and Firefox Nightly.

Key capabilities

  • Connects through CDP(), which defaults to localhost:9222, and returns a client whose domains such as Network and Page are used directly.
  • Subscribes to notifications with handlers such as Network.requestWillBeSent and issues commands including Network.enable(), Page.enable(), Page.navigate(), and the awaited Page.loadEventFired().
  • Manages targets through CDP.List, CDP.New, CDP.Activate, CDP.Close, CDP.Version, and CDP.Protocol, with availability varying by implementation.
  • Drives Chrome and Opera against the tip-of-tree protocol with the full set of protocol, list, new, activate, close, and version operations.
  • Reaches Node.js 6.3.0 and above over the V8 protocol, where a target is the currently inspected script rather than a browser tab.
  • Supports partial implementations including Safari on iOS, Edge, and Firefox Nightly, as documented in the compatibility table.
  • Runs headless since Chrome 59 with the --headless flag, reaches Android through adb -d forward tcp:9222 localabstract:chrome_devtools_remote, and provides a bundled client when installed globally with npm install -g chrome-remote-interface.

Who uses it and how

  • Node.js developers scripting navigation and network observation, as in the README sample that loads https://github.com and logs every request URL.
  • Teams controlling headless Chrome started with --remote-debugging-port=9222, using the library as the control layer in automated browser workflows.
  • Developers debugging a Node.js process, since version 6.3.0 exposes the V8 protocol and the inspected script becomes the target.
  • Mobile testers who forward an Android device's DevTools socket to a local port before driving the device through the same API.
  • Projects that enumerate or open targets before acting, using CDP.List and CDP.New to select the right one.

Getting started

Install with npm install chrome-remote-interface, or globally with -g to use the bundled client. A Chrome instance or another implementation must then be running on a known port, localhost:9222 by default, started for example with google-chrome --remote-debugging-port=9222.

How it compares

No paid or commercial product is listed against which this project can be contrasted, and the facts name no competing library serving the same role. On the evidence provided, it stands alone in this registry as a Chrome Debugging Protocol client for Node.js.

When to use it — and when not to

A self-hoster has to run and manage the target itself, whether that is Chrome or another implementation, and expose its debugging port, since the library does not supply that endpoint. Coverage is uneven: Safari on iOS supports only the protocol and list operations, Edge omits new, activate, and close, and Firefox Nightly is partial, so anyone needing uniform control across those browsers should not expect feature parity. Chrome for Android does not expose the protocol domain at all, so a local protocol version has to be supplied by hand.

project readme (upstream, from github) — read inline

chrome-remote-interface

CI status

[Chrome Debugging Protocol] interface that helps to instrument Chrome (or any other suitable implementation) by providing a simple abstraction of commands and notifications using a straightforward JavaScript API.

Sample API usage

The following snippet loads https://github.com and dumps every request made:

const CDP = require('chrome-remote-interface');

async function example() {
    let client;
    try {
        // connect to endpoint
        client = await CDP();
        // extract domains
        const {Network, Page} = client;
        // setup handlers
        Network.requestWillBeSent((params) => {
            console.log(params.request.url);
        });
        // enable events then start!
        await Network.enable();
        await Page.enable();
        await Page.navigate({url: 'https://github.com'});
        await Page.loadEventFired();
    } catch (err) {
        console.error(err);
    } finally {
        if (client) {
            await client.close();
        }
    }
}

example();

Find more examples in the wiki. You may also want to take a look at the FAQ.

Installation

npm install chrome-remote-interface

Install globally (-g) to just use the bundled client.

Implementations

This module should work with every application implementing the [Chrome Debugging Protocol]. In particular, it has been tested against the following implementations:

Implementation Protocol version Protocol List New Activate Close Version
Chrome tip-of-tree yes¹ yes yes yes yes yes
Opera tip-of-tree yes yes yes yes yes yes
Node.js (v6.3.0+) node yes no no no no yes
Safari (iOS) partial no yes no no no no
Edge partial yes yes no no no yes
Firefox (Nightly) partial yes yes no yes yes yes

¹ Not available on Chrome for Android, hence a local version of the protocol must be used.

The meaning of target varies according to the implementation, for example, each Chrome tab represents a target whereas for Node.js a target is the currently inspected script.

Setup

An instance of either Chrome itself or another implementation needs to be running on a known port in order to use this module (defaults to localhost:9222).

Chrome/Chromium

Desktop

Start Chrome with the --remote-debugging-port option, for example:

google-chrome --remote-debugging-port=9222
Headless

Since version 59, additionally use the --headless option, for example:

google-chrome --headless --remote-debugging-port=9222
Android

Plug the device and make sure to authorize the connection from the device itself. Then enable the port forwarding, for example:

adb -d forward tcp:9222 localabstract:chrome_devtools_remote

After that you should be able to use http://127.0.0.1:9222 as usual, but note that in Android, Chrome does not have its own protocol available, so a local version must be used. See here for more information.

WebView

In order to be inspectable, a WebView must be configured for debugging and the corresponding process ID must be known. There are several ways to obtain it, for example:

adb shell grep -a webview_devtools_remote /proc/net/unix

Finally, port forwarding can be enabled as follows:

adb forward tcp:9222 localabstract:webview_devtools_remote_

Opera

Start Opera with the --remote-debugging-port option, for example:

opera --remote-debugging-port=9222

Node.js

Start Node.js with the --inspect option, for example:

node --inspect=9222 script.js

Safari (iOS)

Install and run the iOS WebKit Debug Proxy. Then use it with the local option set to true to use the local version of the protocol or pass a custom descriptor upon connection (protocol option).

Edge

Start Edge with the --devtools-server-port option, for example:

MicrosoftEdge.exe --devtools-server-port 9222 about:blank

Please find more information here.

Firefox (Nightly)

Start Firefox with the --remote-debugging-port option, for example:

firefox --remote-debugging-port 9222

Bear in mind that this is an experimental feature of Firefox.

Bundled client

This module comes with a bundled client application that can be used to interactively control a remote instance.

Target management

The bundled client exposes subcommands to interact with the HTTP frontend (e.g., List, New, etc.), run with --help to display the list of available options.

Here are some examples:

$ chrome-remote-interface new 'http://example.com'
{
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "id": "b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "thumbnailUrl": "/thumb/b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "title": "",
    "type": "page",
    "url": "http://example.com/",
    "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01"
}
$ chrome-remote-interface close 'b049bb56-de7d-424c-a331-6ae44cf7ae01'

Inspection

Using the inspect subcommand it is possible to perform command execution and event binding in a REPL fashion that provides completion.

Here is a sample session:

$ chrome-remote-interface inspect
>>> Runtime.evaluate({expression: 'window.location.toString()'})
{ result: { type: 'string', value: 'about:blank' } }
>>> Page.enable()
{}
>>> Page.loadEventFired(console.log)
[Function]
>>> Page.navigate({url: 'https://github.com'})
{ frameId: 'E1657E22F06E6E0BE13DFA8130C20298',
  loaderId: '439236ADE39978F98C20E8939A32D3A5' }
>>> { timestamp: 7454.721299 } // from Page.loadEventFired
>>> Runtime.evaluate({expression: 'window.location.toString()'})
{ result: { type: 'string', value: 'https://github.com/' } }

Additionally there are some custom commands available:

>>> .help
[...]
.reset    Remove all the registered event handlers
.target   Display the current target

Embedded documentation

In both the REPL and the regular API every object of the protocol is decorated with the meta information found within the descriptor. In addition The category field is added, which determines if the member is a command, an event or a type.

For example to learn how to call Page.navigate:

>>> Page.navigate
{ [Function]
  category: 'command',
  parameters: { url: { type: 'string', description: 'URL to navigate the page to.' } },
  returns:
   [ { name: 'frameId',
       '$ref': 'FrameId',
       hidden: true,
       description: 'Frame id that will be navigated.' } ],
  description: 'Navigates current page to

readme truncated — read the full docs on github

Frequently asked questions

Is chrome-remote-interface free to use?

chrome-remote-interface is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does chrome-remote-interface do?

Chrome Debugging Protocol interface for Node.js

What is chrome-remote-interface written in?

chrome-remote-interface is primarily written in JavaScript. Its source is publicly available at https://github.com/cyrus-and/chrome-remote-interface, and it has 4,553 GitHub stars.