What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can run Puppeteer without installing Chrome in your application environment by connecting puppeteer-core to a browser running elsewhere. Replace puppeteer.launch() with puppeteer.connect(), provide the remote browser’s WebSocket endpoint, and close the session when the work is done. This keeps your automation code in Puppeteer while moving browser installation, updates, and runtime operations to a managed service or infrastructure you operate.

What “without hosting Chrome” means

Puppeteer needs a browser to control. In a local setup, puppeteer.launch() starts a browser process in the same environment as your JavaScript program. If you do not want to install or run Chrome there, use a browser that is already running on another machine or in a browser service, and connect to it with puppeteer.connect().

This changes where the browser runs, not what Puppeteer is for. After connecting, familiar page operations—including navigation, evaluating page content, waiting for conditions, and generating PDFs—remain available. Your code still orchestrates the browser, but the browser has a separate environment, network location, filesystem, and configuration.

  • Managed browser: A provider starts and operates the browser and gives your application a remote WebSocket endpoint.
  • Self-hosted browser: You run a browser service, for example in a Docker container, and connect to its WebSocket endpoint.
  • Screenshot API: A service accepts a URL and returns an image or PDF. This is useful for capture-only work, but is not a general-purpose remote Puppeteer browser.

Connect Puppeteer to a remote browser

Install puppeteer-core, which provides Puppeteer’s control library without downloading a Chromium binary for your application to launch locally. Obtain the WebSocket endpoint and token from your browser provider; the sample endpoint below follows Browserless’s documented managed-browser pattern. Keep the token in an environment variable or secret store rather than committing it to source control.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install puppeteer-core
import puppeteer from "puppeteer-core";

const TOKEN = process.env.BROWSERLESS_TOKEN;
if (!TOKEN) throw new Error("Set BROWSERLESS_TOKEN before running this script");

const browser = await puppeteer.connect({
  browserWSEndpoint: `wss://production-sfo.browserless.io?token=${TOKEN}`,
});

try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 900 });
  await page.goto("https://example.com", { waitUntil: "networkidle2" });
  console.log(await page.title());
} finally {
  await browser.close();
}

Run the file in an environment that supports ES modules, with BROWSERLESS_TOKEN configured. Substitute the endpoint and token format supplied for your account: regions and endpoint parameters vary by provider. The sample selects a viewport explicitly because the remote browser’s defaults need not match your local browser’s defaults.

What to change in existing code

Local browser workflow Remote browser workflow
puppeteer.launch() starts a browser process in the current environment. puppeteer.connect() attaches to a browser started elsewhere.
Install a Puppeteer package that provides or downloads a browser, if that is how the project is configured. Use puppeteer-core when the application will not launch a bundled local browser.
browser.close() ends the local browser process. browser.close() closes the remote browser session; it does not mean your application has shut down a local Chrome process.

Most page-level code does not need a rewrite. Keep calls such as page.goto(), selector evaluation, waits, and PDF generation, then test them against the remote endpoint. Browserless describes its managed-browser option as intended for teams that already have Puppeteer or Playwright code and want to run it in the cloud without rewriting it.

Choose managed or self-hosted browser infrastructure

Both patterns let an application connect over WebSocket. The important difference is who operates the browser environment. The available documentation establishes the deployment models, but does not provide comparable prices or capacity figures, so compare current provider terms and your own operational requirements rather than assuming one option is cheaper or supports a particular concurrency level.

Consideration Managed browser service Self-hosted container
Infrastructure ownership The provider starts and operates the browser service. Your team provisions, updates, secures, monitors, and scales it.
Setup Connect to the provider’s WebSocket endpoint and configure credentials. Deploy the browser container and expose a reachable WebSocket endpoint.
Scaling and concurrency Confirm available limits and scaling behavior with the provider; the cited documentation does not establish comparable capacity figures. Plan and operate capacity yourself; no specific capacity figure is established here.
Browser versions Check how the provider manages browser versions and when updates apply. Choose and roll out image updates yourself.
Network region Where regional endpoints are available, choose one with the target site’s location and latency in mind. Choose the deployment region and network route you operate.
Observability and security Review the provider’s logging, access controls, retention, and security boundary before sending sensitive work. Configure monitoring, access restrictions, and network security for your service.
Cost Check current plan, usage, session, and timeout terms with the provider. Account for infrastructure and the work required to operate it; no price comparison is established here.

A managed service is a practical starting point when the goal is to avoid operating browser infrastructure. Self-hosting may fit teams that need direct control over deployment and updates and can take responsibility for reliable, secure operation. In either case, check whether the browser’s network access is appropriate for the sites you automate and whether the service’s limits fit your workload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make remote runs reproducible and safe

Set browser context explicitly

A remote browser has its own viewport, user agent, timezone, and locale. If these affect page rendering or behavior, configure them deliberately instead of relying on remote defaults. For example, set the viewport before navigation and set any supported locale or timezone through Puppeteer’s page or context APIs. Keep these values consistent between runs when comparing screenshots or debugging layout differences.

Account for network location and latency

The browser—not your application—makes the request to the target site. The route and distance between that browser region and the site affect navigation latency. If a managed provider offers regional endpoints, select one near the target sites when that is appropriate. A slow navigation is not automatically a Puppeteer bug: distinguish application-to-browser connection delays from browser-to-site loading time.

Do not assume local files are available remotely

A path on your application server is not a path on the remote browser machine. File uploads, downloads, and generated files need an explicit transfer mechanism supported by the browser service, or another storage route your application can reach. Check that mechanism before adapting a script that reads from or writes to local disk.

Always close the session

Put remote work in a try/finally block and call browser.close() in finally. This closes the remote session even if navigation, evaluation, or PDF generation throws an error. An abandoned session may remain open until the provider’s timeout, potentially consuming usage. A timeout is a fallback, not a substitute for cleanup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Headless mode is separate from where Chrome runs

“Headless” describes whether the browser displays a visible window; it does not say whether the browser is local or remote. Puppeteer launches headless by default. The former headless implementation is now called chrome-headless-shell, while headless: false requests a headful Chrome window when launching. Those launch settings do not turn a local browser into a remote one or replace the WebSocket connection step. For remote use, confirm which modes the provider supports and configure the remote browser accordingly.

When a screenshot API is a better fit

If the entire task is “open this public URL and return a screenshot or PDF,” you may not need to manage a Puppeteer session at all. A screenshot API is not a drop-in replacement for scripts that click through workflows, inspect arbitrary page state, or run custom browser logic. For screenshot-only jobs, however, a URL-in/request-out API can avoid browser setup entirely.

Or skip the browser setup

ScreenshotNeo is a screenshot API and MCP server, not a remote Puppeteer endpoint. Use it when your deliverable is a website screenshot or PDF rather than a Puppeteer-controlled browser session. One GET request can return a PNG, JPEG, WebP, or PDF. Its consent-banner cleanup accepts the banner as a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

For example, save a screenshot response from the API with cURL (replace the example URL as needed):

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Equivalent Python and Node.js requests are:

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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for the available parameters and response details. It also offers an MCP server for AI agents using Claude, Cursor, or another MCP client, with take_screenshot, get_page_info, and capture_pdf tools. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Those plan amounts are the listed recurring allowances and prices; yearly billing gives two months free, and every feature is on every plan. Sign up for 1,000 free screenshots a month, with no card required.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting remote Puppeteer

WebSocket connection fails

  • Check the endpoint and token: Copy the full WebSocket endpoint from the provider’s current account settings. Confirm the token is present and valid, and that special characters are encoded as the provider requires.
  • Check outbound connectivity: The runtime must be able to reach the remote endpoint over WebSocket. In restricted CI or serverless networks, verify that outbound rules permit the connection.
  • Check the package: Confirm the project imports puppeteer-core and is not relying on a local launch path that no longer applies.

Navigation times out or is unexpectedly slow

  • Check whether the remote browser can reach the target and whether the site itself is responding.
  • Consider the browser region and target-site region; network distance can affect load time.
  • Choose a navigation wait condition appropriate to the page. A page that keeps background requests open may not satisfy a network-idle condition promptly; if the task only needs a particular element, waiting for that selector can be more relevant.

The screenshot or page differs from local results

  • Set the viewport explicitly, then check the remote browser’s user agent, locale, and timezone.
  • Remember that the remote browser may run a different browser version or use a different network location than your local machine.
  • Check whether the page relies on local files, cookies, or authentication state that your remote session does not have. Transfer or configure the required inputs through supported mechanisms rather than assuming they exist remotely.

Usage continues after the script errors

Make sure the remote connection is created inside a scope that always reaches cleanup, and that browser.close() runs in finally. Also check provider session timeouts and usage rules; the session lifecycle and billing terms are service-specific.

Performance, reliability, and cost decisions

Remote execution removes the need to install Chrome in the application environment, but introduces a network connection to the browser service and a second network journey from that browser to the target site. A closer browser region can reduce the latter latency, while connection or service availability becomes part of the automation’s reliability. For important jobs, handle connection and navigation failures explicitly, use bounded timeouts, and make retries safe for the action being performed; do not blindly retry operations that submit forms or change data.

Keep session lifetimes short by closing browsers in cleanup paths. For managed services, evaluate the provider’s current pricing, concurrency, session timeout, browser version policy, regions, and observability before estimating cost or capacity. For self-hosting, include the operational cost of updating, securing, monitoring, and scaling the container. The documented comparison does not establish common price or throughput figures, so a meaningful cost decision depends on your workload and the current terms of the provider you select.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use Puppeteer’s page methods after connecting remotely?

Yes. The connection changes how Puppeteer gets a browser; page navigation, evaluation, waits, and PDF generation remain available.

Does headless mode mean Puppeteer is running remotely?

No. Headless describes whether the browser displays a window. The local-versus-remote distinction is determined by launching a browser process or connecting to one elsewhere.

Can a screenshot API replace a remote Puppeteer browser?

Only when the job is capture-oriented. A screenshot API returns an image or PDF from a URL; it does not provide the general browser control of a Puppeteer session.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.