# A command line REPL that runs inside a Sauce Labs browser

> browser-repl opens a remote browser session on Sauce Labs and evaluates the lines you type inside that browser, tunneled back to your machine over socket.io. It is a small 2014 era utility with a narrow purpose, useful for poking at a page in a browser you cannot run locally.

**Automattic/browser-repl** — Launch a repl on your command line to any browser in the cloud.

- Repository: https://github.com/Automattic/browser-repl
- Stars: 731 · Forks: 28
- Language: JavaScript
- License: not declared
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/automattic-browser-repl

## What the tool is actually for

browser-repl is described as a CLI utility to set up a remote browser repl, and the repository description puts the goal plainly: launch a repl on your command line to any browser in the cloud. The point is to get a JavaScript evaluation loop running inside a browser you do not have locally.

That is a specific, slightly old-fashioned need. It suits someone debugging a page that behaves differently on a browser stack they cannot install, or someone writing a small script of DOM probes against a cloud browser. It is not a general remote browser automation framework, and the tool does not pretend to be one.

The scope is visible in the repository layout. The top level holds a handful of files: Readme.md, History.md, a Makefile, browsers.json, client.js, repl.js and package.json. There is no src directory, no test suite and no API surface exported for other code to call. The package exposes exactly one executable.

Two names appear in the project. The contributors listed are Nathan Rajlich and Guillermo Rauch, and the README states the licence is MIT, Copyright 2014 Automattic, Inc. The npm package name is browser-repl, with a hyphen, and the binary it installs is called repl.

## webdriver opens the session, socket.io carries the input

The mechanism has two halves, and the README describes them separately. browser-repl is built on top of the wd module, which is an implementation of the webdriver protocol. That is the remote control layer: it is what talks to the cloud browser service and establishes the browser session.

Once a browser session is established, socket.io is used to establish a persistent connection that works on all browsers as fast as possible. So the webdriver side handles the browser lifecycle, and the socket.io side handles the interactive channel. The phrase as fast as possible is doing quiet work there, since a persistent socket avoids paying the cost of a new connection for every line you type.

The direction of travel is worth being precise about, because it is unusual. The socket.io server is hosted locally, on the machine where you run the command. The remote browser connects back to it. That inversion is what makes the design work across browsers and across the network boundary of a hosted browser service.

The client side is a single file, client.js, and the Makefile shows how it is assembled into a browser bundle with browserify, producing static/build.js as the build target.

## The reverse tunnel is how the remote browser finds your machine

A remote browser cannot reach a socket.io server on your laptop directly, so the tool sets up a reverse tunnel with localtunnel. The README says this gives your computer a temporary URL of the format https://{uid}.localtunnel.me. The remote browser is pointed at that URL, and the tunnel carries the connection back to the socket.io server running on your machine.

This is the mechanism with the sharpest edges in the whole project, for a structural reason rather than a bug. A publicly routable URL is what makes the connection possible at all, and it also means that for the lifetime of the tunnel your local socket.io server is reachable from the internet under a guessable uid.localtunnel.me hostname. The README does not describe any access control on that endpoint. Anyone who knows the URL could attempt to drive the same session.

The dependency list shows two tunnelling era packages, ngrok at 0.1.99 and localtunnel referenced in the README through a link to a repository under the defunctzombie account. Both point at tooling that has since moved on. Nothing in the documentation describes how the tunnel is torn down, what happens to the temporary URL when the process exits, or whether it can be pointed at a private tunnel instead.

## Installing the CLI and pointing it at Sauce Labs

The usage section gives three commands, and they are the entire setup path. Two environment variables carry the Sauce Labs credentials, and the third argument names the browser to open.

```bash
$ npm install -g browser-repl
$ export SAUCE_USERNAME="your username"
$ export SAUCE_ACCESS_KEY="your key"
$ repl ie6
```

The installation is a global npm install, which means the command is available on your PATH from any directory. The credentials are read from the environment rather than from a config file, so nothing has to be committed to a repository, and the browser name is passed as a positional argument to the repl binary.

The README points you to Sauce Labs and says to sign up for a free OSS account. That is a hard prerequisite rather than a suggestion, since the webdriver session is what the tool drives, and the example browser name in the snippet, ie6, is a legacy Internet Explorer target that the account has to be able to provision.

The binary itself is declared in package.json under bin, mapped to the repl.js file, which is the entry point you run.

## Every line is eval'd, and window.onerror watches for failures

The evaluation semantics are stated in three short sentences in the README. The lines you enter are subsequently eval'd. A global window.onerror hook is also set to capture errors. Summoning repl with the -n argument disables this.

The first of those is the whole design: the input is not a command language, it is JavaScript evaluated in the page. There is no expression parser, no command set and no output formatting to learn. What you type runs the way it would in a console, which is convenient for quick probing and unhelpful for anything structured.

The second sentence is the useful part for a debugging session. By default the page's errors are captured through a global hook, so a failure inside your evaluation surfaces in the terminal instead of disappearing into the browser. The -n flag turns that off, which matters if your own code installs its own error handler and you would rather not have it replaced.

What the README does not say is where the output of a console.log call goes, how the result of the final expression is rendered, or whether the page is reloaded between evaluations. For a tool whose entire interface is the printed output, those gaps matter, and there is no documented session log or transcript format to fall back on.

## Dependency pins and a build step that predates modern bundlers

The package.json tells a story about its age. Every runtime dependency is pinned to an exact version, and the pins are from the period when npm packages were installed this way: express 4.22.0, socket.io 2.5.0, socket.io-client 1.3.5, wd 0.3.11, minimist 1.2.6, ngrok 0.1.99, plus small helpers such as array-map, foreach, to-array and util-inspect.

Some of those pins are old enough that a current Node installation may not install them cleanly, which is the main practical risk in adopting this project today. The socket.io 2.x line and the socket.io-client 1.x line are paired here, and they are not versions anyone ships in a new project in 2026.

The build story is the second hint. The only build script in package.json is prepublish, which runs make build. The Makefile builds static/build.js from client.js using browserify, with the browserify binary pinned at 8.1.3 in devDependencies. A prepublish hook tied to a Makefile is a workflow from before the npm scripts ecosystem settled, and it means the published artifact depends on a build that only runs on a machine with make and the right Node tooling.

There is a History.md file for release notes and the repository has no GitHub releases. The last push was on 2026-09-24, so the code is being touched, but there is no tag history to work with when planning an upgrade.

## Licence terms are MIT on paper and unreadable in the listing

The licence is the one field that needs a caveat. The README states MIT, Copyright 2014 Automattic, Inc., and the package.json file declares the same MIT licence identifier for the published package. However, the licence could not be read from the project listing, so a repository-level licence file should be checked directly before the code is vendored into a product.

Taken at face value, MIT is a permissive licence with no copyleft obligation and no requirement that derived works be published, which makes the code easy to reuse in an internal tool if you need to modify it. There is no separate grant needed for the browser code, since client.js is bundled into the tool itself.

The maintenance picture is the last practical consideration. The last push was on 2026-09-24, which is recent, so the repository is not abandoned and the last commit did land after the release dates of the packages it depends on. What that date does not tell you is whether the old pins were refreshed, because the README, the package.json file and the History.md changelog are the only sources describing the state of the project, and none of them list a modernised dependency set.

## Conclusion

Take browser-repl if you need interactive JavaScript inside a Sauce Labs browser and already have an OSS account, and skip it if you need a modern browser matrix tool or a scriptable API, since the package exposes one binary and no library API. Before installing, check that the old pins in package.json, notably socket.io 2.5.0 and wd 0.3.11, still resolve on your Node version, and keep in mind that the reverse tunnel publishes your local socket.io server on a temporary public URL.

## FAQ

### How do I install and run browser-repl?

Install it globally with npm install -g browser-repl, export SAUCE_USERNAME and SAUCE_ACCESS_KEY, then run the repl binary with a browser name such as repl ie6. You need a Sauce Labs OSS account for the remote browser session to work.

### How does browser-repl send my input to the remote browser?

The wd module, an implementation of the webdriver protocol, establishes the browser session, and socket.io is used to establish a persistent connection afterwards. The socket.io server is hosted locally and reached from the browser through a reverse tunnel set up with localtunnel, which gives your computer a temporary URL of the form https://{uid}.localtunnel.me.

### What does the -n flag do in browser-repl?

By default a global window.onerror hook is set to capture errors. Summoning repl with the -n argument disables that hook.

### What licence is browser-repl released under?

The README states MIT, Copyright 2014 Automattic, Inc., and package.json declares MIT for the npm package, although the licence could not be read from the project listing and the LICENSE file should be checked directly.

### Does browser-repl expose an API for other code to call?

No. The package declares a single binary named repl mapped to repl.js, and the repository contains no exported library entry point or test suite, so it is a command line tool rather than a programmable dependency.

## Sources

- [Automattic/browser-repl on GitHub](https://github.com/Automattic/browser-repl)
- [Issues](https://github.com/Automattic/browser-repl/issues)
- [README](https://github.com/Automattic/browser-repl/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/automattic-browser-repl
