n8n-nodes-puppeteer: browser automation inside a workflow
n8n node for browser automation using Puppeteer
At a glance
- What is it?
- This community node puts a real browser inside a workflow engine. A step in the pipeline can open a page, capture what it looks like as a screenshot or a PDF, scrape the contents, or run a script of your own against the page, and it talks to Chrome or Firefox through the browser's debugging protocol rather than by pretending to be a browser.
- Who is it for?
- n8n-nodes-puppeteer fits a team that already builds its automation in a workflow engine and needs a browser step in the middle of it, whether for scraping, for capturing evidence, or for driving a site that has no API. It does not fit a workload where the browser is the exception, because a headless browser in a pipeline is an expensive dependency.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 168 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the node does
The node is described as an n8n node for browser automation using Puppeteer, and the readme's summary of the capability is a list: execute custom scripts, capture screenshots and PDFs, scrape content, and automate web interactions using the browser's debugging protocol.
That last clause is the important one. A browser automation tool has to speak to a browser, and the modern way to do that is through the browser's own debugging interface rather than by driving the window from the operating system. The readme calls out full access to the Puppeteer API alongside the capabilities of the workflow engine's own scripting node, and it says plainly that the combination is what makes the node useful for browser automation tasks.
So the node is not a thin wrapper around a scraping library. It gives a workflow step the entire Puppeteer interface, which means that if Puppeteer can do something, a workflow can do it, and if the workflow engine can do something, the same step can do it. The node reference lists four operations: getting the full HTML of a page, capturing the contents of a page as a PDF document, capturing a screenshot of all or part of the page, and executing a custom script to interact with the page.
Those four cover the three things people actually want from a browser in an automated pipeline. The HTML operation is for reading the page. The PDF operation is for producing a document that looks like the page, which is what you want when the output has to be a report rather than a data set. The screenshot operation is for capturing evidence, and it can take all of the page or part of it. And the custom script operation is the escape hatch for everything else, and the one that makes the node more than a set of presets.
The options list is where the practical detail lives. There is a batch size, which is the maximum number of pages to open at the same time, with the warning that more pages consume more memory and processor. There is a browser endpoint, a protocol choice, a device to emulate, a path to the browser executable, and extra headers to send with the request.
The project is MIT licensed, written in TypeScript, and the last push was in May 2026 with the newest release in January of that year.
Installing it, three ways, and the one the readme recommends
There are three installation routes, and the readme is explicit about which to use when.
The first is the community nodes panel of the workflow engine, and it is marked as the recommended route for the versions from 0.187 onwards. The steps are short: go to the settings, then to the community nodes section, choose install, type the package name, agree to the risks of using community nodes, and install.
That last step, agreeing to the risks, is worth a moment. The workflow engine's documentation has a page on the risks of community nodes, and requiring an explicit acknowledgement of them is a design decision by the engine rather than by this node. The reason is obvious once you think about it: a community node runs inside the workflow engine's own process, with its access to the engine's configuration and to whatever the workflow can reach, and a node that drives a browser is by definition a node that can be pointed at anything.
The second route is a container, and the readme marks it as the recommended one for production. The setup is a clone, a build, and a run, with a script for each.
npm run docker:buildnpm run docker:runAnd a third script for testing without persistent data, which is the one to reach for when you want to check the image works and do not care about keeping the engine's data volume.
The third route is a manual install, which is the one for an existing engine installation on a machine you control.
# Navigate to your n8n root directory
cd /path/to/n8n
# Install the package
npm install n8n-nodes-puppeteerAnd then the note that makes the container recommendation obvious. By default, when Puppeteer is installed it downloads a compatible version of Chromium, and while that works it increases the installation size and may not include the necessary system dependencies. For production, the readme recommends either the container setup or installing a system Chrome and setting the environment variable that skips the download.
So the choice is between a browser in the image and a browser on the machine, and the readme's advice is that the image is the one you want in production.
The container, and the arguments it adds for you
The image is worth reading, because it shows what a browser needs in a container and what a project has to decide for itself.
It starts from the workflow engine's own published image, which means the node inherits the engine's runtime rather than shipping a second copy of it. The first build step is unusual: it fetches the static package manager for the distribution, installs it, and then uses it to add the package manager itself to the image. The reason is visible in the comments, which are written in the voice of somebody who fought this: there is a note saying that a way of doing the install in its own image could not be found, and another marking a piece of hard coding as something to be fixed.
Then the browser and its dependencies are installed: the browser itself, the network security library, the base graphics library, the font rendering stack with its development headers, the text shaping library, the certificate store, and three separate font packages, one of which is for emoji. The fonts are not decoration. A screenshot of a page whose fonts are missing is a screenshot of the wrong page, and the emoji font in particular is what stops a document from rendering as a row of empty boxes.
Then two environment variables tell the automation library not to download its own browser and where the system one is, and the node is installed into a permanent location with the engine's own workflow package alongside it, then built, and the ownership is handed to the unprivileged user.
And then there is the part that shows the project has been run in production. When the node detects that it is running in a container or in a cluster, it adds the launch arguments that a browser needs in that environment: no sandbox, no setuid sandbox, a shared memory workaround, and the graphics acceleration disabled. The readme says this happens automatically with no configuration needed, and that a banner appears in the node when a container is detected, which can be switched off in the options if it is in the way.
The last detail is the entry point. The image does not start the engine directly; it runs a custom script, and the working directory and the environment are arranged so that the custom node is found. The image ends by switching to the unprivileged user and invoking that script.
Remote browsers, and the two protocols
The second browser setup is the one that matters for a cloud deployment, and it is called the remote browser option.
Instead of launching a browser, the node connects to one that is already running, over a WebSocket endpoint. The readme lists the reasons and they are all about operations rather than about the browser itself: it removes the need for the browser's dependencies in the engine's environment, it simplifies deployment and maintenance, it gives better resource isolation, and it suits cloud and containerised deployments. The fifth reason is different in kind: it supports Firefox, through the WebDriver BiDi protocol.
That last point is the significant technical detail. There are two ways to drive a browser remotely, and the node supports both. The default is the Chrome DevTools protocol, which is what Chrome and Chromium speak. The alternative is the WebDriver BiDi protocol, which is the cross-browser standard that Firefox speaks.
The managed services are named as the easy option, with two hosted browser providers, and then there is the self-hosted route, with a container image for a browser and a note about the self-hosted Firefox option.
docker run -p 3000:3000 -e "TOKEN=6R0W53R135510" ghcr.io/browserless/chromiumThe configuration can be set per node, by adding options to any node in the workflow: the endpoint, and the protocol, with the Chrome protocol as the default and the Firefox one as the alternative. It can also be set globally with environment variables, and the readme recommends that route.
# For Chrome/Chromium
docker run -it -p 5678:5678 \
-e PUPPETEER_BROWSER_WS_ENDPOINT=ws://browserless:3000 \
-e PUPPETEER_PROTOCOL=cdp \
n8n-puppeteerAnd the same thing again for Firefox, with the different endpoint and the other protocol value.
# For Firefox
docker run -it -p 5678:5678 \
-e PUPPETEER_BROWSER_WS_ENDPOINT=ws://firefox:4444 \
-e PUPPETEER_PROTOCOL=webDriverBiDi \
n8n-puppeteerA compose file is given as well, with the engine and a browser service side by side.
version: '3.8'
services:
n8n:
image: n8n-puppeteer
environment:
- PUPPETEER_BROWSER_WS_ENDPOINT=ws://browserless:3000
- PUPPETEER_PROTOCOL=cdp
ports:
- "5678:5678"
browserless:
image: browserless/chrome
ports:
- "3000:3000"When the variables are set, a banner appears showing the endpoint that has been configured, and individual nodes can still override it. That combination, a sensible global default with a per-node escape hatch, is the right way round: most workflows want the same browser, and the one that does not should not need the whole environment to change.
Troubleshooting, and the project around the node
The troubleshooting section is short and specific, and it is about the single most common failure mode of running a browser in a container.
If you see errors about missing shared libraries, such as the object introspection library or the network security library, there are two ways out. You can install the missing dependencies, or you can switch to a remote browser with the WebSocket endpoint option. And for anything else, the readme points at the automation library's own troubleshooting guide.
That is a well-chosen pair of remedies, because the second one is the better one. A missing shared library means the image is missing a system package, and chasing them one at a time is a long process. Moving the browser out of the image removes the whole class of problem, which is the argument the remote browser section was making in the first place.
The repository layout is small and matches the shape of a workflow engine node. There is an entry file, a directory for the nodes themselves, a build file for the task runner, a directory for the container setup, a directory of images, and the usual configuration files. There is also a linter configuration for the older TypeScript linter, which is a sign of a project that has been around long enough for its tooling to have been superseded but has not rewritten it, and the watch script for the type compiler is the usual way to develop a node against the engine's types.
The package manifest shows the shape of the toolchain, and the docker scripts are worth a look because they are the ones a user actually runs. The build and run scripts are the basic pair, and then there is a run script for a locally built image, a fresh run without a data volume, and a run against an external browser with the endpoint pointed at the host, which is the developer case of the remote browser option. There is a test script that runs the image and asks the engine for its version, which is a smoke test in the useful sense: it proves the image starts and the engine is loadable, which is most of what a broken image is.
And there is a shell script for opening a shell inside the container for debugging, plus two clean scripts, one that removes the data volume and one that removes the volume and the images. A tool that runs a browser in a container will have a broken state at some point, and a way in is worth more than a paragraph of explanation.
Editorial conclusion
n8n-nodes-puppeteer fits a team that already builds its automation in a workflow engine and needs a browser step in the middle of it, whether for scraping, for capturing evidence, or for driving a site that has no API. It does not fit a workload where the browser is the exception, because a headless browser in a pipeline is an expensive dependency. Verify first whether your pages need a real browser or would do with a plain request, since a browser step costs far more, and how the browser is deployed, because the local and remote arrangements have quite different operational profiles.
Frequently asked questions
What does the n8n-nodes-puppeteer node do?
It adds browser automation to a workflow. Four operations are available: getting the full HTML of a page, capturing the page as a PDF document, capturing a screenshot of all or part of the page, and running a custom script against the page, with the whole Puppeteer API available in that last operation.
How do I install the n8n Puppeteer node?
Through the community nodes panel in the engine's settings for versions from 0.187 onwards, by entering the package name and agreeing to the risks. The readme also recommends a container setup for production, and a manual package install for a standard installation, with a note that the browser download can be skipped in favour of a system Chrome.
Can the n8n Puppeteer node drive a remote browser?
Yes. Set the browser WebSocket endpoint and the node connects to a browser that is already running rather than launching one, which removes the browser's system dependencies from the engine's environment and suits cloud deployments. The Chrome DevTools protocol is the default and the WebDriver BiDi protocol is available for Firefox, and the endpoint can be set per node or globally with environment variables.
Why does the n8n Puppeteer container image install fonts and extra libraries?
Because a browser in a container needs the graphics, text shaping, certificate and font packages to render a page correctly, and a screenshot of a page with missing fonts is a screenshot of the wrong page. The image also disables the browser's sandbox and shared memory options automatically when it detects a container, and a banner in the node tells you it has done so.
What should I do if I get missing shared library errors with the n8n Puppeteer node?
Install the missing browser dependencies, or move the browser out of the image entirely by switching to a remote browser with the WebSocket endpoint option, which is the remedy the readme recommends because it removes the whole class of problem rather than one library at a time.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/drudge-n8n-nodes-puppeteer)Was this useful?