Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a browser runner when your JavaScript must execute against a real URL. A tool such as browser-run starts a browser (Electron by default), reads JavaScript from standard input, and streams console output. Use npm exec (or its npx alias) when the npm package exposes a command you want to invoke; npm can resolve a package, version, tag, tarball URL, or Git URL for that command. These are different jobs: one supplies a page context with location and the DOM, while the other launches a Node-oriented executable.
Choose the execution model first
The phrase “run JavaScript on a URL” can mean two different things. Decide which one matches your code before installing anything.
Browser-context code
Choose a browser runner when the script needs window, document, location, cookies, layout, or other page APIs. The browser actually opens (or serves) content, then evaluates your script in that page. browser-run is designed for this workflow and describes itself as “The easiest way of running code in a browser environment.”
Node command with an npm dependency
Choose npm exec when a package provides a command-line program. It resolves the requested package and runs its executable, but it does not navigate to a URL or create a DOM by itself. Your command must perform any HTTP request, browser launch, or other URL handling.
#1 Best Overall
| Need | Use | What you get |
|---|---|---|
| Read or modify a live page | browser-run |
Browser globals, DOM, page navigation and console output |
| Invoke a package’s CLI | npm exec/npx |
Node process and the package’s command arguments |
| Run in Linux CI without a display | Browser runner plus Xvfb | A virtual display for headed-browser software |
Install and run browser-run
One-off installation
Install locally in a project so the version is recorded in package.json and your lockfile:
npm install browser-run
For a globally available command, the project documents:
npm install -g browser-run
The CLI reads JavaScript from standard input. This minimal example prints the page location and then closes the browser:
echo "console.log('Hey from ' + location); window.close()" | browser-run
Expect the CLI to report a localhost page URL while it starts its web server and browser. Calling window.close() is important in scripts that should terminate unattended; otherwise the browser can remain open waiting for more input.
Use a script file
Put browser code in a file and pipe it to the command:
cat > inspect.js <<'EOF'
console.log('URL:', location.href)
console.log('Title:', document.title)
console.log('Links:', document.links.length)
window.close()
EOF
cat inspect.js | browser-run
Your code runs with page APIs, so DOM queries work without importing a DOM shim. The page URL available through location.href is the URL the browser runner opened or served for that run.
Accept HTML input
The CLI defaults to JavaScript input. With --input html, pass an HTML file instead:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Rank #2
browser-run --input html page.html
This is useful for testing local markup and scripts. Keep the input mode explicit in automation so a JavaScript file is not accidentally interpreted as HTML.
Load npm packages in the page workflow
npm defines a package as a file or directory described by package.json. Registry names, exact versions, tags, tarball URLs and Git URLs are valid package references. A module in node_modules is loaded with require or import; a loose JavaScript file is not an npm package unless it is described by a package manifest.
Node-side modules and browser-side modules are different
A dependency installed with npm is normally resolved by Node. Browser code can use it only when the runner makes that module available to the page (for example, through a browser-compatible bundle or an explicit Node-integration option). A package that uses filesystem, child-process, or other Node-only APIs cannot automatically run in an ordinary web page.
Keep the boundary visible in your project:
- Page code: DOM and browser APIs, with no assumption that
requireexists. - Node harness: npm imports, filesystem setup, URL selection, and orchestration.
- Bridge: only the values you intentionally pass between the harness and page.
Node integration is a deliberate security decision
browser-run exposes a Node-integration switch. Enabling it can make Node APIs available to page code, but it changes the browser’s security model: code loaded from the target page may gain capabilities you did not intend to grant. Keep the default isolation whenever possible. If integration is unavoidable, use trusted content, restrict network access, and treat the run as code execution with access to the credentials and files available to the process.
Free tools Windows power users keep installed
One-click scans. No signup required.
Browser-run options that matter in automation
The project documents options for selecting a browser, enabling or disabling its sandbox, serving static assets, mocking requests, enabling Node integration, and setting a basedir for requiring modules in Node mode.
Browser and sandbox
Electron is the default browser. Select another supported browser when your page depends on a particular engine. The sandbox is enabled by default; do not disable it merely to hide an installation problem. In CI, first fix missing display or dependency issues, then change isolation only with a documented reason.
Static files and a basedir
Use static assets when the page under test references local JavaScript, CSS, images, or fixtures. Set basedir to the directory from which Node-mode modules should resolve so that relative imports behave consistently on a developer machine and in CI.
Request mocking
Mock requests for deterministic tests or to avoid sending test data to a production endpoint. A mock is not evidence that the real URL behaves the same; keep at least one separate integration run against the real service.
Run a package command with npm exec
When the package itself supplies a CLI, use npm’s documented forms:
npm exec -- <pkg>[@<version>] [args...]
npm exec --package=<pkg>[@<version>] -- <cmd> [args...]
For example, the package can be resolved for one invocation rather than added permanently to your project:
npm exec --package=some-cli@1 -- some-cli --help
The npx alias provides the familiar equivalent:
npx some-cli --help
Pin a version in repeatable jobs. An unqualified package name may resolve a newer release later, changing output or command-line behavior. For production builds, record the version in your project or specify it explicitly in the command and review the resulting lockfile or npm cache policy.
What npm exec does not do
npm exec does not open a webpage, wait for client-side rendering, or provide document. If the CLI needs a URL, pass that URL using the CLI’s own documented option. If you need to execute JavaScript inside that page, use a browser automation or browser-run workflow instead.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Headless Linux and continuous integration
A browser runner normally needs a display, even when no physical monitor is attached. The project documents Xvfb for display-less systems and shows GitHub Actions usage with xvfb-run npm test.
xvfb-run npm test
Adapt the command to your script, for example:
xvfb-run --auto-servernum sh -c 'cat inspect.js | browser-run'
Make CI runs predictable:
- Install the same browser and npm dependency versions used locally.
- Use an explicit timeout around the job so a page that never closes cannot consume a runner indefinitely.
- Close the page with
window.close()after assertions and logging. - Capture standard output and standard error as build artifacts when diagnosing failures.
- Separate network-dependent tests from mocked tests and label them accordingly.
Working with arbitrary URLs safely
Navigation and page readiness
A URL can return a redirect, an error page, or HTML that never finishes loading. Log location.href after navigation and wait for the page state your script actually needs rather than assuming the first response is the final document. For dynamic applications, a selector or application-specific readiness signal is more reliable than a fixed short delay.
Rank #4
Authentication and secrets
Do not place passwords or API keys in a URL, shell history, or source file. Supply secrets through the CI secret store or environment variables, and pass only the minimum data to the browser context. Clear test profiles after runs if they contain session cookies.
Cross-origin limits
Browser security rules still apply. A script running on one origin cannot freely read another origin’s DOM merely because it navigated there. Use an approved server-side API, configure the target application for the required access, or run separate page-context scripts for each origin.
Untrusted URLs
If users can submit the URL, treat this as a server-side request-forgery and code-execution boundary. Restrict schemes to HTTP(S), block internal address ranges, isolate the browser process, disable Node integration, and enforce CPU, memory, and time limits.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting
browser-run: command not found
The package is not installed globally or its npm bin directory is not on PATH. Install it locally and invoke the project binary through your package scripts, or install globally and verify the global npm bin path.
The process hangs after printing output
The browser is still open or a pending timer/request keeps the event loop alive. Call window.close() after the final operation, and add a harness-level timeout for failed navigations.
“Display” or Electron startup errors in CI
Run the command under Xvfb as documented, confirm the browser dependencies are installed, and preserve the full startup error. Do not immediately disable the sandbox; that is a separate security trade-off.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
require is undefined in page code
That is expected in an isolated browser page. Bundle a browser-compatible dependency, move the import to the Node harness, or deliberately enable Node integration only for trusted content.
Best Value
The npm command runs but the URL is unchanged
You invoked a package CLI, not a page runner. Pass the URL using that CLI’s documented argument, or switch to browser-run when the JavaScript must access the page DOM.
Results differ between local and CI
Compare browser choice, viewport, locale, environment variables, installed package versions, network availability, and whether requests were mocked. Pin versions and record the final URL and readiness signal in logs.
Or skip the browser setup
If your goal is a reliable screenshot or PDF of a URL rather than custom in-page computation, ScreenshotNeo provides a single HTTP call. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; response headers identify the page verdict and whether it was billed.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →See the complete parameter list in the ScreenshotNeo documentation. cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every feature is on every plan; 1,000 screenshots per month are free with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Performance, reliability, and cost decisions
- Local browser runner: best when you need arbitrary JavaScript, DOM assertions, request mocks, or access to local fixtures. Browser startup and CI display setup add operational work.
- npm exec: simplest for a package command; remote resolution is convenient but should be version-pinned for repeatability.
- Screenshot service: avoids browser installation and manages capture-specific cleanup. Check the returned verdict and billing headers rather than assuming every response was a successful page.
For high-volume jobs, reuse a controlled browser process where the runner supports it, avoid unnecessary full-page work, and set explicit timeouts. For screenshots, caching with a chosen TTL and bulk capture can reduce repeated requests; ScreenshotNeo supports both, along with asynchronous jobs and signed webhooks.
Frequently Asked Questions
Can I use any npm package directly inside a webpage?
No. The package must be browser-compatible or bundled for the browser. Packages requiring Node-only APIs such as the filesystem need to stay in the Node harness or run with deliberately enabled integration.
Is npx different from npm exec?
npx is npm’s alias for invoking a package executable; the documented npm exec forms make package and command boundaries explicit.
Do I need Xvfb on every headless run?
Only when the browser software requires a display and your Linux runner has none. The browser-run project documents Xvfb for that environment; a desktop runner with a real display does not need it.
How do I prove which URL was actually tested?
Log location.href from the page after navigation. This reveals redirects and the final origin instead of relying only on the input string.
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.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minute

