The n8n Puppeteer node is n8n-nodes-puppeteer, a community node that drives a headless Chrome from your workflow: open a page, run a Puppeteer script, save a screenshot or a PDF. It works, but the browser has to live inside your n8n instance, and n8n installs unverified community nodes like this one only on self-hosted n8n.
That is where most searches for it start: a browser that won't launch, missing Chrome libraries, a custom Docker image. Below is the community-node route as it really is, for Puppeteer and Playwright, then what Browserless offers, then the route we recommend: run the browser on Scrape.ly and call it from n8n, so your n8n container never needs Chrome. We tested that route on a JavaScript-rendered page on 28 October 2026.
n8n browser automation: your options at a glance
| Route | Where Chrome runs | n8n Cloud | You write | What comes back |
|---|---|---|---|---|
n8n-nodes-puppeteer | Inside your n8n container, or a browser you host and connect to | No: unverified community nodes need self-hosting | A Puppeteer script | What your script returns, plus screenshots and PDFs |
n8n-nodes-playwright | Inside your n8n container (about 1 GB of browser binaries) | No, same rule | Steps or a Playwright script | Page content, text, screenshots |
| Browserless | Browserless's cloud or your own Browserless server | The HTTP Request route works on any n8n | Endpoint calls, BrowserQL or a function | The endpoint's response |
| Scrape.ly Actor | Scrape.ly's cloud | Yes: the Scrape.ly node is a verified community node, and the HTTP Request route works on any n8n | A page function, or nothing for a ready-made scraper | Rows, one n8n item each |
What the n8n Puppeteer node does
n8n-nodes-puppeteer has four operations: get the full HTML of a page, capture it as a PDF, capture a screenshot, and run a custom script. The custom script gets $page, $browser and $puppeteer plus everything the Code node offers, so anything Puppeteer can do, the node can do.
The options are where it gets useful for scraping:
- Stealth mode, powered by
puppeteer-extra-plugin-stealth. Our Puppeteer stealth test shows what that plugin patches and what it still leaves visible. - Proxy Server, Emulate Device, Extra Headers and a navigation Timeout.
- Browser WebSocket Endpoint, to connect to a browser running somewhere else instead of launching one.
- Capture Downloads, which returns files a click downloads as binary data.
It also works as a tool for n8n AI agents: an agent can write the whole script through $fromAI(), or pass a URL into a fixed script as $input.query.
How to install the n8n Puppeteer node, and where it breaks
On self-hosted n8n, an owner or admin goes to Settings → Community Nodes → Install, enters n8n-nodes-puppeteer and accepts the risks of unverified code. On n8n Cloud there is no such option. n8n's docs say it plainly: "Unverified community nodes aren't available on n8n cloud and require self-hosting n8n."
Installing the package is the easy part. The node launches Chrome in the same container as n8n, and that's where it breaks:
- Missing system libraries. Puppeteer downloads a Chromium on install, which, in the node's own words, "may not include necessary system dependencies". The README's troubleshooting section names errors about
libgobject-2.0.so.0andlibnss3.so. The top forum threads for this search read the same: "requires lib and chrome dependencies", "Failed to launch/connect to browser". - A custom Docker image. The fix the README recommends for production is its own Docker setup: n8n plus Alpine's Chromium, fonts and libraries. Others publish ready images with Puppeteer and Chromium pre-installed. Either way, you now build your own n8n image and rebuild it whenever n8n updates.
- Or a remote browser. Set the Browser WebSocket Endpoint (or
PUPPETEER_BROWSER_WS_ENDPOINT) to a Chrome you run elsewhere. That removes the libraries from n8n, but you still host a browser, and you still need self-hosted n8n for the node.
Don't expect the node on n8n Cloud soon, either. n8n's verification guidelines require a package with no external dependencies that never reads environment variables or files. A node that bundles Puppeteer and reads PUPPETEER_* variables doesn't fit those rules as written.
The n8n Playwright node
The Playwright side looks the same. n8n-nodes-playwright offers Navigate, Take Screenshot, Get Text, Click Element, Fill Form and Run Custom Script, in Chromium, Firefox or WebKit. It downloads the browser binaries during installation, which "requires approximately 1GB of disk space", and its README warns that "additional system dependencies may be required". It's an unverified community node too, so self-hosted only.
Search results for "n8n playwright node" also turn up forks for persistent sessions and for running raw Playwright code, plus a forum thread about the node's paths on macOS. Picking a library won't save you the hosting work; if you are still choosing, our Playwright vs Puppeteer and Puppeteer vs Selenium comparisons cover the differences that matter for scraping.
Run the browser on Scrape.ly instead
The browser doesn't have to run in n8n at all. On Scrape.ly, an Actor is a cloud program that takes JSON input and returns rows. The Web Scraper Actor with useChrome turned on loads each page in Chromium, waits until the network goes quiet, and runs your page function on the DOM after the page's scripts have run. That's the job most people install the Puppeteer node for.
The Chrome runs on Scrape.ly's side: our run's log shows the launch redirected to a remote browser. Pages load through Scrape.ly's residential proxy by default, and you pay per row of data, platform usage included. For popular sites, the Scrape.ly Store has 570+ ready-made Actors that return structured data with no page function at all. If headless browsers are new to you, what is a headless browser explains what is happening on the other end.
From n8n you call the Actor in one of two ways.
Option 1: the Scrape.ly n8n node
The n8n-nodes-scrapely community node is an API client only: no browser, no runtime dependencies. That's why n8n verified it, so it installs on n8n Cloud and self-hosted n8n alike, straight from the nodes panel:
- In n8n, open the nodes panel, search for Scrapely and pick the version with the verified badge, then click Install (an instance owner or admin does this once). Self-hosted instances can also install
n8n-nodes-scrapelyunder Settings → Community nodes → Install. - Create a Scrapely API credential with an API token from the Scrape.ly dashboard (Settings → API & Integrations). A scoped key needs
actors:run,runs:readanddatasets:read. - Add the Scrapely node with Resource Actor and Operation Run. Pick the Actor from the searchable list or type its ID,
querystone/web-scraper, and paste the input JSON shown below. - Leave Wait for Finish and Return Results on. The node waits up to Max Wait (3,600 seconds by default), then outputs each row as one n8n item, up to Results Limit (1,000 by default).
The same node works as a tool for n8n AI agents. The Scrapely Trigger starts a workflow when a run succeeds, fails, times out or is aborted, and with Include Results on it hands you the rows instead of the event. The n8n docs page lists every operation, and our n8n web scraping guide has example workflows.
Option 2: the HTTP Request node, on any n8n
The HTTP Request node is built into n8n, so this route also works on n8n Cloud. It calls the run-sync endpoint, which starts the run, waits for it and returns the rows as a JSON array:
curl -X POST "https://api.scrape.ly/v2/actors/querystone~web-scraper/run-sync-get-dataset-items?maxTotalChargeUsd=0.05" \
-H "Authorization: Bearer $SCRAPELY_TOKEN" \
-H "Content-Type: application/json" \
-d @input.jsonIn the node, that is:
| Setting | Value |
|---|---|
| Method | POST |
| URL | https://api.scrape.ly/v2/actors/querystone~web-scraper/run-sync-get-dataset-items?maxTotalChargeUsd=0.05 |
| Authentication | Generic Credential Type, Header Auth: header Authorization, value Bearer plus your API token |
| Send Body | On, Body Content Type JSON, Specify Body Using JSON, with the input below |
| Options → Timeout | 60000 (milliseconds), so n8n waits out the sync window |
maxTotalChargeUsd caps what the run can spend. The endpoint waits up to 45 seconds. If a run takes longer, it answers 408 and the run keeps going; don't call the endpoint again, because that starts a second run. Jobs that regularly run longer belong in the Scrape.ly node, which waits until the run finishes. The Actors API docs list every endpoint.
A real run: a JavaScript page in Chrome, two pages deep
quotes.toscrape.com/js is a practice site whose quotes don't exist in the HTML: a script writes them into the page. Fetch it with the HTTP Request node and you get no quotes. This is the input we sent, the same body the node or the HTTP Request node sends:
{
"startUrls": [{ "url": "https://quotes.toscrape.com/js/" }],
"useChrome": true,
"linkSelector": "li.next a",
"maxPagesPerCrawl": 2,
"pageFunction": "async function pageFunction(context) {\n const $ = context.jQuery;\n return $('.quote').map((i, el) => ({\n page: context.request.url,\n text: $(el).find('.text').text(),\n author: $(el).find('.author').text(),\n tags: $(el).find('.tag').map((j, t) => $(t).text()).get(),\n })).get();\n}",
"respectRobotsTxtFile": true,
"proxyConfiguration": { "useScrapelyProxy": true }
}The page function, readable:
async function pageFunction(context) {
const $ = context.jQuery;
return $('.quote').map((i, el) => ({
page: context.request.url,
text: $(el).find('.text').text(),
author: $(el).find('.author').text(),
tags: $(el).find('.tag').map((j, t) => $(t).text()).get(),
})).get();
}useChrome renders each page in Chromium, linkSelector follows the "Next" link, and maxPagesPerCrawl stops after two pages. The run (ID 540abbc8542d49858) logged:
2026-10-28T13:32:18.191Z [scrapely.actor] INFO Done: 2 pages fetched, 20 records saved, Chrome avg per page: open 0.6s goto 0.8s idle 0.5s scroll 0.7s snapshot 0.2s in 13 s
2026-10-28T13:32:18.191Z [scrapely.actor] INFO [Status message]: Saved 20 results from 2 pages. Stopped at Max pages per run (2); raise it to crawl more.It returned 20 rows, ten from each page, in 16 seconds end to end, well inside the 45-second sync window. A few of them:
| page | author | text | tags |
|---|---|---|---|
| /js/ | Albert Einstein | "The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking." | change, deep-thoughts, thinking, world |
| /js/ | J.K. Rowling | "It is our choices, Harry, that show what we truly are, far more than our abilities." | abilities, choices |
| /js/ | Marilyn Monroe | "Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring." | be-yourself, inspirational |
| /js/page/2/ | Albert Einstein | "If you can't explain it to a six year old, you don't understand it yourself." | simplicity, understand |
In n8n, each of those rows arrives as one item, ready for Google Sheets, a database or an AI step. The 20 rows cost from $0.01144. For more ways to handle pages like this, see how to scrape dynamic websites.
Porting a Puppeteer script to a page function
Most Puppeteer-node scripts for scraping map onto Web Scraper fields:
| In the Puppeteer node | In the Web Scraper |
|---|---|
$page.goto(url) | startUrls |
waitUntil: 'networkidle2' | waitUntil, networkidle2 by default |
$page.$$eval() over a selector | jQuery in the page function (context.jQuery) |
| A loop that clicks "Next" | linkSelector with maxPagesPerCrawl |
| Clicking or typing before you read | A post-navigation hook, which receives the Chromium page |
| The Proxy Server option | proxyConfiguration, residential by default |
return [...] | Each returned object becomes one row |
Scrolling for lazy content is built in (maxScrollHeightPixels), and so is dismissing cookie dialogs (closeCookieModals).
Where the Browserless node fits
Browserless runs Chrome as a hosted service, or as a container you run yourself, and the Puppeteer node's README lists it among the browsers you can point the WebSocket endpoint at. From n8n you can call it two ways. Its own docs give HTTP Request templates for screenshots, PDFs, page content, unblocking, CSS-selector scraping, BrowserQL and custom functions, with the API token as a query parameter. And Browserless publishes a community node, n8n-nodes-browserless-api, with operations such as Smart Scrape, Screenshot, PDF, Crawl, Run Function and Run Agent.
It's a good fit if you want a remote browser and plan to keep writing browser code. Scrape.ly takes you one step further: you pay for rows of data rather than a browser, and for popular sites a ready-made Store Actor already returns structured fields, with no browser code for you to keep working when the site changes.
What it costs
The Web Scraper charges one event per row your page function returns, platform usage (compute, proxy and browser) included. Price checked on the Store page on 28 October 2026: from $0.572 per 1,000 results, whether a page loads over HTTP or in Chrome. Pages that return nothing aren't charged.
Our run returned 20 rows, which cost from $0.01144. The Free plan's $5 of monthly usage covers about 6,900 results, with no credit card. Paid plans and their limits are on the pricing page. There's no Chrome server to pay for or patch.
FAQ
Can I use the Puppeteer node on n8n Cloud?
No. n8n Cloud runs only verified community nodes, and n8n-nodes-puppeteer isn't one. To drive a browser from n8n Cloud, install the verified Scrapely node from the nodes panel and run a browser Actor such as the Web Scraper, or call the same Actor through the built-in HTTP Request node with the request shown above.
Does the Scrape.ly node work on n8n Cloud?
Yes. n8n-nodes-scrapely is a verified community node, so an owner or admin can install it from the nodes panel on n8n Cloud or self-hosted n8n: search for Scrapely, pick the version with the verified badge and click Install.
Is there an n8n Playwright node?
Not a built-in one. n8n-nodes-playwright is a community node with navigate, click, fill, text, screenshot and custom-script operations. It downloads about 1 GB of browser binaries on install and runs on self-hosted n8n only.
How do I add Puppeteer to n8n in Docker?
Build an image that adds Chromium, its fonts and libraries to the n8n image, then install n8n-nodes-puppeteer in it. The node's repository includes a Docker setup for this. The alternative is to point the node's Browser WebSocket Endpoint at a browser running in another container, or to skip both and run the browser on Scrape.ly.
Why does n8n-nodes-puppeteer fail to launch the browser?
Usually because Chrome's system libraries are missing from the n8n container: errors name files such as libnss3.so. Install the dependencies, use an image with Chromium included, or connect to a remote browser.
Does n8n have a built-in browser automation node?
No. n8n's core nodes include HTTP Request, HTML and Code, but no headless browser. The HTTP Request node fetches a page's HTML without running its JavaScript, which is why it finds no quotes on the page in our run.
Can an n8n AI agent control a browser?
Yes, through a tool. The Puppeteer node can run as an agent tool with an AI-written script. The Scrape.ly node also works as an agent tool, so an agent can run a browser-backed Actor and read the rows it returns.




