chrome-launcher: Launch Chrome from Node.js
Launch Google Chrome with ease from node.
At a glance
- What is it?
- chrome-launcher starts Chrome with remote debugging enabled, selects an installed browser, and manages temporary profiles. It fits Node.js tools that need direct DevTools Protocol access, but Puppeteer may be a better fit when higher-level browser automation is required.
- Who is it for?
- Adopt chrome-launcher when a Node.js tool needs a short-lived Chrome process and direct DevTools Protocol access without taking on a full browser automation framework. Do not choose it for page navigation, waiting, or browser actions that Puppeteer already handles.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why chrome-launcher Exists for Node.js Tools
chrome-launcher addresses a narrow part of browser automation: starting Google Chrome in a state that another program can control. A Node.js tool needs a running browser process, a known communication channel, and predictable cleanup. The package searches for Chrome, opens its remote debugging port on an available port, creates a fresh profile for each launch, and removes that profile when `kill()` completes.
The intended users are developers building measurement tools, browser-related utilities, or services that speak the DevTools Protocol directly. It is also relevant to projects that need control over the spawned Chrome process and its command-line flags. The package does not provide page-level automation after startup. The README directs users to a DevTools Protocol client such as `chrome-remote-interface`, while noting that Puppeteer is recommended for many cases.
This boundary matters. If the application needs to click elements, navigate through page states, take screenshots through a conventional API, or manage a complete browser session, Puppeteer offers its own launching mechanism and a higher-level interface. chrome-launcher is more appropriate when direct process lifecycle control and an exposed debugging endpoint are the central requirements. Its small API can also be easier to integrate into a tool that already has protocol handling.
How chrome-launcher Starts and Exposes Chrome
The central operation is `.launch([opts])`. By default, the launcher selects an available debugging port, but callers can supply a specific `port`. If that requested port is busy, `launch()` rejects rather than silently choosing a different port. This makes explicit port selection predictable, although the caller must ensure that another process is not already using it.
Chrome selection follows a documented order. An explicit `chromePath` takes precedence. If it is absent, the launcher checks `CHROME_PATH`. A detected Chrome Canary can then take priority over a detected stable Chrome installation. The `ChromeLauncher.Launcher.getInstallations()` API returns paths to available installations. Its documentation also warns that the method performs synchronous I/O, which is worth considering in services that must keep event-loop work nonblocking.
Each normal launch uses a fresh user data directory unless `userDataDir` is set. The default is intended to isolate automation from a user's normal Chrome profile. After launch, the returned interface includes `port`, `pid`, `process`, `kill()`, and `remoteDebuggingPipes`. `kill()` terminates Chrome and cleans up the generated profile folder.
Most launches communicate over the debugging port. When `chromeFlags` includes `--remote-debugging-pipe`, however, `port` is unusable and defaults to `0`. Protocol messages instead travel through `remoteDebuggingPipes.incoming` and `remoteDebuggingPipes.outgoing`. Those streams carry JSON values terminated by a NULL byte. This pipe mode removes the TCP port dependency but requires the consuming tool to implement the pipe protocol correctly.
Installing chrome-launcher and Opening a Browser
The package requires Node.js `>=12.13.0` and is published as `chrome-launcher`. Install it into an existing Node.js project with npm. The README also documents Yarn as an alternative.
npm install chrome-launcherThe npm command adds the package to the project's dependencies. The repository's package metadata identifies `./dist/index.js` as the main entry point and marks the package as an ES module.
The following first launch imports the package, requests a starting URL, and reports the assigned debugging port. It is the README's launch example:
import * as ChromeLauncher from 'chrome-launcher';
ChromeLauncher.launch({
startingUrl: 'https://google.com'
}).then(chrome => {
console.log(`Chrome debugging port running on ${chrome.port}`);
});A successful call supplies a `chrome` object whose `port` is the endpoint exposed by Chrome. The example prints that port but does not connect to the browser. Actual interaction must happen through the DevTools Protocol, such as through `chrome-remote-interface` or another compatible client.
For headless operation, the README supplies these flags:
import * as ChromeLauncher from 'chrome-launcher';
ChromeLauncher.launch({
startingUrl: 'https://google.com',
chromeFlags: ['--headless', '--disable-gpu']
}).then(chrome => {The command-line flags are added to those selected by the launcher. The package also configures many Chrome flags by default. Review `src/flags.ts` and `docs/chrome-flags-for-tools.md` before adding flags for a production workload.
Profile Isolation, Cleanup, and Signal Handling
Temporary profile creation is one of the package's clearest engineering decisions. A fresh profile prevents a launch from inheriting cookies, local storage, and preferences from the user's everyday Chrome profile. That isolation is useful for repeatable tool runs and reduces accidental interference with a normal browsing session.
The generated profile is cleaned up by `chrome.kill()`. Applications should retain the returned launcher object so they can terminate the exact process they started. The package also exposes `ChromeLauncher.killAll()`, which attempts to terminate every Chrome instance created through `.launch()` and resolves with an array of errors encountered during cleanup.
import * as ChromeLauncher from 'chrome-launcher';
async function cleanup() {
await ChromeLauncher.killAll();
}An empty returned array means that the attempted terminations succeeded. Nonempty entries report failures, so callers can inspect cleanup problems rather than assuming every process ended.
By default, the launcher handles `SIGINT` and `SIGTERM`. `handleSIGINT` can disable this behavior when the host application owns signal processing. The README does not describe rollback or recovery after an interrupted launch. It also does not promise durable cleanup after abnormal process termination. For long-running workers, the explicit lifecycle decision belongs in application code: either call `kill()` for one browser or use `killAll()` when tracking several instances.
Launch Controls and Their Operational Trade-offs
The options expose several decisions that are usually hidden inside higher-level browser tools. `portStrictMode` changes how an already occupied requested port is handled. With the default `false`, the launcher can start a new Chrome instance at that port. With `true`, it throws when no Chrome is found there. The README positions this case for connecting to an already running Chrome, including one reached through a setup such as `adb`.
`startingUrl` defaults to `about:blank`. `logLevel` accepts `'verbose'`, `'info'`, `'error'`, or `'silent'`, with silence as the default. `envVars` passes environment entries to the spawned Chrome process. These controls are useful when the tool and browser must run under a constrained service account, although the package does not document a complete browser sandbox policy.
Readiness is controlled by `connectionPollInterval` and `maxConnectionRetries`. Their defaults are 500 milliseconds and 50 attempts respectively. A low maximum retry count may reject too quickly on a slow or loaded machine. Increasing retries can accommodate slower startup but delays failure reporting. Neither option changes how the consuming tool uses the DevTools Protocol.
`ignoreDefaultFlags` allows code to retain only the flags returned by `ChromeLauncher.Launcher.defaultFlags()` while replacing package defaults through `chromeFlags`. The documented default-flags result excludes `--remote-debugging-port`, `--disable-setuid-sandbox`, and `--user-data-dir`. This is a low-level composition point. Overriding defaults can affect startup, communication, or isolation, so the relevant decision is to inspect `src/flags.ts` rather than infer the resulting command from the API alone.
chrome-launcher Compared with Puppeteer
The clearest alternative named by the project is Puppeteer. The difference is not that Puppeteer cannot launch Chrome. It has its own Chrome launching mechanism. The difference is the interface offered after startup.
chrome-launcher stops at process creation, debugging access, and cleanup. It returns a port, process information, kill function, or optional debugging pipes. It does not offer the README's examples for page automation because browser interaction remains the caller's responsibility.
Puppeteer is recommended by the chrome-launcher README for many use cases. Projects centered on browser automation can use that higher-level mechanism rather than building separate protocol handling. chrome-launcher remains relevant when the tool already manages Chrome through the DevTools Protocol and only needs the launcher. It also offers direct control over port selection, strict port behavior, process environment variables, default flags, startup URL, readiness polling, and pipe transport.
There is no documented guarantee that one approach produces fewer errors or better performance. The practical choice depends on scope. Using Puppeteer adds its browser automation API and launching behavior to the design. Using chrome-launcher keeps the dependency focused on launching but leaves protocol implementation and page actions to the application. The npm metadata does not list Puppeteer as a dependency, so adopting chrome-launcher does not automatically install it.
Maintenance, Upgrades, and Apache-2.0 Packaging
The repository is not archived. Its last push was on 2026-10-05, and the package version in `package.json` is `1.2.2`. Recent releases include v1.2.2 on 2026-09-29, v1.2.1 on 2025-09-25, and v1.2.0 on 2025-05-06. This establishes recent repository activity, but it does not by itself guarantee compatibility with every future Chrome release.
Because Chrome flags and remote debugging behavior can evolve, upgrades deserve attention to the release notes and the current contents of `src/flags.ts`. Consumers should also check their Node.js version against the declared `>=12.13.0` engine requirement. The repository includes TypeScript sources, tests, formatting checks, and build scripts, while the published package points consumers to compiled files under `dist`.
The package metadata declares the Apache-2.0 license. Source and binary redistribution therefore needs to be reviewed against that license and any applicable notices, along with the terms of transitive dependencies. This is not legal advice. For maintenance planning, the immediate check is whether a newer `chrome-launcher` version changes launch defaults, pipe behavior, or cleanup handling that the consuming tool relies on.
Editorial conclusion
Adopt chrome-launcher when a Node.js tool needs a short-lived Chrome process and direct DevTools Protocol access without taking on a full browser automation framework. Do not choose it for page navigation, waiting, or browser actions that Puppeteer already handles. Before adoption, verify that the target machines have an acceptable Chrome installation, confirm whether the tool needs port or pipe communication, and read the default flags in src/flags.ts to ensure that they fit the automation environment.
Frequently asked questions
How do I install chrome-launcher?
Run `npm install chrome-launcher` or add it with `yarn add chrome-launcher`. The package requires Node.js `>=12.13.0`.
Does chrome-launcher automate Chrome pages after launch?
No. Browser interaction must be performed through the DevTools Protocol, typically with a client such as `chrome-remote-interface`. The README recommends Puppeteer for many automation cases.
How can chrome-launcher use the DevTools Protocol over pipes?
Pass `--remote-debugging-pipe` in `chromeFlags`. The debugging port is then unusable and defaults to `0`, while protocol traffic uses `remoteDebuggingPipes.incoming` and `remoteDebuggingPipes.outgoing`.
How does chrome-launcher terminate Chrome instances?
Call `chrome.kill()` for one launched instance and its temporary profile. `ChromeLauncher.killAll()` attempts to terminate all instances created through `.launch()` and returns an array containing any cleanup errors.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/googlechrome-chrome-launcher)Was this useful?