Recommended Free Tools
To record a remote Selenium browser session, configure video capture on the Selenium Grid deployment—not in Express.js. Node.js sends WebDriver commands to Grid; the browser runs on a remote node; a Docker Selenium video-recorder container captures the session and writes the video to mounted storage or uploads it to configured object storage.
Express is optional: use it to accept a request or queue an automation job, but it is not a video recorder or Selenium middleware. The configuration depends on whether you use standalone Docker, Hub/Node, or Dynamic Grid, so choose the topology before copying recorder settings.
How the pieces fit together
A remote video workflow has three roles:
- Express.js application (optional): accepts an application request and starts or coordinates automation.
- Selenium WebDriver client: your Node.js code uses the Selenium JavaScript binding to send commands to a remote WebDriver endpoint.
- Grid browser and recorder: the Grid runs the browser session, while the deployment’s video recorder captures it and stores the resulting file.
Express does not record the browser stream. You can run the same WebDriver code from a Node.js script or test runner if you do not need an HTTP API. The Selenium JavaScript API documents remote connection through usingServer() and SELENIUM_REMOTE_URL; the Grid quick start uses http://localhost:4444 as its default RemoteWebDriver address. See Selenium Grid documentation and the Selenium JavaScript API.
Choose a recording topology before configuring it
Docker Selenium’s setup differs by deployment mode. Do not assume that recorder environment variables, session capabilities, or output paths are interchangeable.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches#1 Best Overall
| Topology | Recording approach | Where to check output |
|---|---|---|
| Standalone Docker Selenium | Run a browser container with the video-recorder container configured to capture its session. | The host directory mounted for recordings, as configured in the selected Compose or container setup. |
| Hub/Node | Pair the recorder with the relevant browser node and configure shared or mounted output storage as documented for that deployment. | The configured host-mounted output directory. |
| Dynamic Grid | Docker Selenium documents session-level recording with the se:recordVideo capability. |
The host-mounted assets/output directory used by the Dynamic Grid configuration. |
These are topology distinctions, not a claim that one mode is universally best. Consult the current Docker Selenium README for the exact configuration and paths matching the images you deploy. Its image tags and defaults change; the README showed Selenium 4.48.0 and dated image tags on September 5, 2026, which should not be treated as permanent values. Pin compatible versions rather than copying a tag without checking.
Connect a Node.js client to remote Selenium
Install the Selenium JavaScript binding in your project. Its current API documentation requires Node.js 22 or later. Keep the Grid address configurable so the same code can target a local Grid during development and a private Grid endpoint in CI or deployment.
npm install selenium-webdriver
For a standalone script, set the remote URL in the environment and run a session. This example navigates to a page, performs an action, and always attempts to close the WebDriver session so the recorder can observe session closure.
Rank #2
const { Builder, Browser, By } = require('selenium-webdriver');
async function main() {
const gridUrl = process.env.SELENIUM_REMOTE_URL || 'http://localhost:4444';
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.usingServer(gridUrl)
.build();
try {
await driver.get('https://example.com');
console.log(await driver.findElement(By.css('h1')).getText());
} finally {
await driver.quit();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Install and configure the browser and recorder on the Grid side separately. The client code does not create a video file by itself. If you prefer, the Selenium JavaScript API also supports configuring the remote server through SELENIUM_REMOTE_URL; check the API version you install for the exact builder behavior.
Enable Docker Selenium video capture
Follow the Docker Selenium instructions for the topology you selected and ensure the video recorder is associated with the browser session. In common Compose deployments the recorder runs as a separate container. Its output storage must be mounted or shared according to the documented configuration.
- Start Grid and its browser node. Make the WebDriver endpoint reachable from the Node.js process, but do not expose it publicly.
- Add/configure the recorder for that topology. Use the matching Docker Selenium documentation rather than transplanting settings from a Dynamic Grid example into a Hub/Node setup.
- Mount a host output directory. Confirm the recorder writes to the intended path and that the host or CI job can read it after the containers stop.
- Run the session with a display-capable browser configuration. Docker Selenium states that video recording for headless browsers is unsupported in its documented setup.
- Close the session with
await driver.quit(). The recorder uses session lifecycle events to start and stop in event-driven configurations. - Retrieve the artifact. Read it from the mounted directory or configure the recorder’s documented Rclone-based upload destination.
For Dynamic Grid, use the documented se:recordVideo capability when requesting a session. The precise capability and output configuration should be taken from the current Docker Selenium README for the image version and deployment mode in use.
Rank #3
Use Express to trigger jobs without tying up requests
An Express route can accept a job request and start automation, but a long-running browser session may exceed client, proxy, or server request timeouts. A production-friendly design typically queues the work, returns a job identifier, and exposes a separate status or artifact endpoint. Make sure each job has cleanup logic and that concurrent sessions cannot overwrite one another’s recordings.
The following is a minimal illustration of the coordination pattern, not a complete queue or production job system. It waits for the job in the request, so for lengthy sessions you should replace the inline wait with a queue and polling or callback workflow.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
const express = require('express');
const { Builder, Browser } = require('selenium-webdriver');
const app = express();
app.use(express.json());
app.post('/run-browser-job', async (req, res) => {
const gridUrl = process.env.SELENIUM_REMOTE_URL || 'http://localhost:4444';
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.usingServer(gridUrl)
.build();
try {
await driver.get(req.body.url || 'https://example.com');
const title = await driver.getTitle();
res.json({ title, status: 'finished' });
} catch (error) {
res.status(500).json({ error: 'Browser job failed' });
} finally {
await driver.quit();
}
});
app.listen(process.env.PORT || 3000);
Validate allowed target URLs and inputs before launching a browser; do not let an untrusted caller use your automation service to navigate internal systems. In a queue-based design, record the job ID, session ID, outcome, and artifact location, and return only authorized artifact links.
Rank #4
Find and retain the video
With mounted storage, the recorder writes to the path configured for its topology. Confirm the host-side mount, container-side destination, and CI artifact collection path all agree. The output directory may differ between standalone, Hub/Node, and Dynamic Grid examples.
Docker Selenium’s recorder image includes Rclone and documents uploads to destinations including S3 and GCS. Uploading is useful when artifacts must outlive containers or be fetched by another CI stage; mounted files are simpler when the job runner can collect them directly. The documentation does not establish a generally cheaper storage provider, so compare retention, access controls, transfer behavior, and your provider’s pricing for your workload.
Keep cloud credentials in deployment secrets or an equivalent secret manager. Do not put them in source code or an Express route. When running parallel sessions, use unique or automatic filenames: the Docker Selenium project warns that multiple video containers need distinct file naming to avoid unexpected results.
Best Value
Plan capacity, reliability, and security
- CPU: Docker Selenium says to normally estimate one CPU per video container and one CPU per browser container. This is a planning guideline, not a benchmark or universal minimum.
- Headless mode: the project says, “Video recording for headless browsers is not supported.” Use a supported display-capable setup when video is required.
- Session cleanup: use
finallyto calldriver.quit()on success and failure; in event-driven mode, recording follows session-created and session-closed events. - Grid security: Selenium’s guide says, “Selenium Grid must be protected from external access using appropriate firewall permissions.” Keep port 4444 private or firewall-restricted. An exposed Grid can allow access to infrastructure, internal sites or files, and execution of custom binaries. See Getting started with Selenium Grid.
- Version compatibility: pin compatible Selenium and recorder/browser image versions, then check the current Docker Selenium README when upgrading because tags and defaults are volatile.
Troubleshooting common recording failures
| Symptom | Likely cause | What to check |
|---|---|---|
| No video file appears | Recorder is not enabled or paired with the browser, output mount is wrong, or the session did not close normally. | Verify the topology-specific recorder configuration, host/container mount mapping, and that code reaches driver.quit(). |
| Video is missing for headless sessions | The documented Docker Selenium recorder setup does not support headless recording. | Use a display-capable browser configuration. |
| Node.js cannot connect to Grid | The URL may be wrong or the endpoint may not be reachable from the client container or host. | Check SELENIUM_REMOTE_URL, port 4444, network/DNS context, and Grid health from the same environment where Node runs. |
| Parallel jobs overwrite or produce unexpected files | Recorder containers may be using colliding output names. | Configure distinct or automatic filenames as supported by the selected Docker Selenium setup. |
| Grid session starts but recording stops unexpectedly | Session lifecycle or recorder configuration may not match the chosen topology. | Check recorder logs and verify the session creation/closure behavior and version-matched setup instructions. |
| Uploads fail or credentials are rejected | Rclone destination, permissions, or secrets may be misconfigured. | Check the documented S3/GCS-compatible configuration and secret injection without printing credentials into logs. |
Or skip the browser setup
If you need a static screenshot rather than a recording of a sequence of browser interactions, ScreenshotNeo takes screenshots or PDFs through a single API request; it does not replace Selenium video capture. For a screenshot, use the API call below. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie/consent banners and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.
FAQ
Does Selenium itself save the remote browser video?
The WebDriver client sends commands; in Docker Selenium’s documented configuration, video capture is handled by deployment-side recorder infrastructure.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCan I record a local browser session with this setup?
This workflow is specifically for a remote Grid session. Local browser execution does not automatically use the separate Docker Selenium Grid recorder arrangement.
Is Express.js required?
No. Express is useful when an application needs to trigger or coordinate browser jobs; a test runner or Node.js script can connect to Grid directly.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

