Gathering detailed insights and metrics for puppeteer-extra
Gathering detailed insights and metrics for puppeteer-extra
Gathering detailed insights and metrics for puppeteer-extra
Gathering detailed insights and metrics for puppeteer-extra
puppeteer-extra-plugin
Base class for puppeteer-extra plugins.
puppeteer-extra-plugin-stealth
Stealth mode: Applies various techniques to make detection of headless puppeteer harder.
puppeteer-extra-plugin-user-preferences
Launch puppeteer with arbitrary user preferences.
puppeteer-extra-plugin-user-data-dir
Custom user data directory for puppeteer.
npm install puppeteer-extra
Typescript
Module System
Min. Node Version
Node Version
NPM Version
66.3
Supply Chain
97.1
Quality
73.7
Maintenance
100
Vulnerability
98.9
License
JavaScript (59.86%)
TypeScript (39.86%)
HTML (0.19%)
Shell (0.09%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
6,939 Stars
604 Commits
758 Forks
115 Watchers
5 Branches
49 Contributors
Updated on Jul 16, 2025
Latest Version
3.3.6
Package Id
puppeteer-extra@3.3.6
Unpacked Size
144.58 kB
Size
22.54 kB
File Count
12
NPM Version
lerna/3.22.1/node@v18.12.1+arm64 (darwin)
Node Version
18.12.1
Published on
Mar 01, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
3
3
19
A light-weight wrapper around
puppeteer
and friends to enable cool plugins through a clean interface.
1yarn add puppeteer puppeteer-extra 2# - or - 3npm install puppeteer puppeteer-extra 4 5# puppeteer-extra works with any puppeteer version: 6yarn add puppeteer@2.0.0 puppeteer-extra
1// puppeteer-extra is a drop-in replacement for puppeteer, 2// it augments the installed puppeteer with plugin functionality. 3// Any number of plugins can be added through `puppeteer.use()` 4const puppeteer = require('puppeteer-extra') 5 6// Add stealth plugin and use defaults (all tricks to hide puppeteer usage) 7const StealthPlugin = require('puppeteer-extra-plugin-stealth') 8puppeteer.use(StealthPlugin()) 9 10// Add adblocker plugin to block all ads and trackers (saves bandwidth) 11const AdblockerPlugin = require('puppeteer-extra-plugin-adblocker') 12puppeteer.use(AdblockerPlugin({ blockTrackers: true })) 13 14// That's it, the rest is puppeteer usage as normal 😊 15puppeteer.launch({ headless: true }).then(async browser => { 16 const page = await browser.newPage() 17 await page.setViewport({ width: 800, height: 600 }) 18 19 console.log(`Testing adblocker plugin..`) 20 await page.goto('https://www.vanityfair.com') 21 await page.waitForTimeout(1000) 22 await page.screenshot({ path: 'adblocker.png', fullPage: true }) 23 24 console.log(`Testing the stealth plugin..`) 25 await page.goto('https://bot.sannysoft.com') 26 await page.waitForTimeout(5000) 27 await page.screenshot({ path: 'stealth.png', fullPage: true }) 28 29 console.log(`All done, check the screenshots. ✨`) 30 await browser.close() 31})
The above example uses the stealth
and adblocker
plugin, which need to be installed as well:
1yarn add puppeteer-extra-plugin-stealth puppeteer-extra-plugin-adblocker 2# - or - 3npm install puppeteer-extra-plugin-stealth puppeteer-extra-plugin-adblocker
If you'd like to see debug output just run your script like so:
1DEBUG=puppeteer-extra,puppeteer-extra-plugin:* node myscript.js
puppeteer-extra
and most plugins are written in TS, so you get perfect type support out of the box. :)
1import puppeteer from 'puppeteer-extra' 2 3import AdblockerPlugin from 'puppeteer-extra-plugin-adblocker' 4import StealthPlugin from 'puppeteer-extra-plugin-stealth' 5 6puppeteer.use(AdblockerPlugin()).use(StealthPlugin()) 7 8puppeteer 9 .launch({ headless: false, defaultViewport: null }) 10 .then(async browser => { 11 const page = await browser.newPage() 12 await page.goto('https://bot.sannysoft.com') 13 await page.waitForTimeout(5000) 14 await page.screenshot({ path: 'stealth.png', fullPage: true }) 15 await browser.close() 16 })
Please check this wiki entry in case you have TypeScript related import issues.
1const vanillaPuppeteer = require('puppeteer') 2 3const { addExtra } = require('puppeteer-extra') 4const AnonymizeUA = require('puppeteer-extra-plugin-anonymize-ua') 5 6async function main() { 7 const pptr1 = addExtra(vanillaPuppeteer) 8 pptr1.use( 9 AnonymizeUA({ 10 customFn: ua => 'Hello1/' + ua.replace('Chrome', 'Beer') 11 }) 12 ) 13 14 const pptr2 = addExtra(vanillaPuppeteer) 15 pptr2.use( 16 AnonymizeUA({ 17 customFn: ua => 'Hello2/' + ua.replace('Chrome', 'Beer') 18 }) 19 ) 20 21 await checkUserAgent(pptr1) 22 await checkUserAgent(pptr2) 23} 24 25main() 26 27async function checkUserAgent(pptr) { 28 const browser = await pptr.launch({ headless: true }) 29 const page = await browser.newPage() 30 await page.goto('https://httpbin.org/headers', { 31 waitUntil: 'domcontentloaded' 32 }) 33 const content = await page.content() 34 console.log(content) 35 await browser.close() 36}
puppeteer-cluster
puppeteer-cluster allows you to create a cluster of puppeteer workers and plays well together with
puppeteer-extra
.
1const { Cluster } = require('puppeteer-cluster') 2const vanillaPuppeteer = require('puppeteer') 3 4const { addExtra } = require('puppeteer-extra') 5const Stealth = require('puppeteer-extra-plugin-stealth') 6const Recaptcha = require('puppeteer-extra-plugin-recaptcha') 7 8async function main() { 9 // Create a custom puppeteer-extra instance using `addExtra`, 10 // so we could create additional ones with different plugin config. 11 const puppeteer = addExtra(vanillaPuppeteer) 12 puppeteer.use(Stealth()) 13 puppeteer.use(Recaptcha()) 14 15 // Launch cluster with puppeteer-extra 16 const cluster = await Cluster.launch({ 17 puppeteer, 18 maxConcurrency: 2, 19 concurrency: Cluster.CONCURRENCY_CONTEXT 20 }) 21 22 // Define task handler 23 await cluster.task(async ({ page, data: url }) => { 24 await page.goto(url) 25 26 const { hostname } = new URL(url) 27 const { captchas } = await page.findRecaptchas() 28 console.log(`Found ${captchas.length} captcha on ${hostname}`) 29 30 await page.screenshot({ path: `${hostname}.png`, fullPage: true }) 31 }) 32 33 // Queue any number of tasks 34 cluster.queue('https://bot.sannysoft.com') 35 cluster.queue('https://www.google.com/recaptcha/api2/demo') 36 cluster.queue('http://www.wikipedia.org/') 37 38 await cluster.idle() 39 await cluster.close() 40 console.log(`All done, check the screenshots. ✨`) 41} 42 43// Let's go 44main().catch(console.warn)
For using with TypeScript, just change your imports to:
1import { Cluster } from 'puppeteer-cluster' 2import vanillaPuppeteer from 'puppeteer' 3 4import { addExtra } from 'puppeteer-extra' 5import Stealth from 'puppeteer-extra-plugin-stealth' 6import Recaptcha from 'puppeteer-extra-plugin-recaptcha'
chrome-aws-lambda
If you plan to use chrome-aws-lambda with the
stealth
plugin, you'll need to modify the default args to remove the--disable-notifications
flag to pass all the tests.
1const chromium = require('chrome-aws-lambda') 2const { addExtra } = require('puppeteer-extra') 3const puppeteerExtra = addExtra(chromium.puppeteer) 4 5const launch = async () => { 6 puppeteerExtra 7 .launch({ 8 args: chromium.args, 9 defaultViewport: chromium.defaultViewport, 10 executablePath: await chromium.executablePath, 11 headless: chromium.headless 12 }) 13 .then(async browser => { 14 const page = await browser.newPage() 15 await page.goto('https://www.spacejam.com/archive/spacejam/movie/jam.htm') 16 await page.waitForTimeout(10 * 1000) 17 await browser.close() 18 }) 19} 20 21launch() // Launch Browser
Kikobeats/browserless
Kikobeats/browserless is a puppeteer-like Node.js library for interacting with Headless production scenarios.
1const puppeteer = require('puppeteer-extra') 2const StealthPlugin = require('puppeteer-extra-plugin-stealth') 3puppeteer.use(StealthPlugin()) 4 5const browserless = require('browserless')({ puppeteer }) 6 7const saveBufferToFile = (buffer, fileName) => { 8 const wstream = require('fs').createWriteStream(fileName) 9 wstream.write(buffer) 10 wstream.end() 11} 12 13browserless 14 .screenshot('https://bot.sannysoft.com', { device: 'iPhone 6' }) 15 .then(buffer => { 16 const fileName = 'screenshot.png' 17 saveBufferToFile(buffer, fileName) 18 console.log(`your screenshot is here: `, fileName) 19 })
puppeteer-extra-plugin-stealth
puppeteer-extra-plugin-recaptcha
page.solveRecaptchas()
.puppeteer-extra-plugin-adblocker
puppeteer-extra-plugin-devtools
puppeteer-extra-plugin-repl
puppeteer-extra-plugin-block-resources
puppeteer-extra-plugin-flash
puppeteer-extra-plugin-anonymize-ua
puppeteer-extra-plugin-user-preferences
puppeteer-extra-plugin-font-size
.Check out the packages folder for more plugins.
These plugins have been generously contributed by members of the community. Please note that they're hosted outside the main project and not under our control or supervision.
puppeteer-extra-plugin-minmax
puppeteer-extra-plugin-portal
Please check the
Contributing
section below if you're interested in creating a plugin as well.
PRs and new plugins are welcome! 🎉 The plugin API for puppeteer-extra
is clean and fun to use. Have a look the PuppeteerExtraPlugin base class documentation to get going and check out the existing plugins (minimal example is the anonymize-ua plugin) for reference.
We use a monorepo powered by Lerna (and yarn workspaces), ava for testing, TypeScript for the core, the standard style for linting and JSDoc heavily to auto-generate markdown documentation based on code. :-)
puppeteer-extra
and all plugins are tested continously in a matrix of current (stable & LTS) NodeJS and puppeteer versions.
We never broke compatibility and still support puppeteer down to very early versions from 2018.
A few plugins won't work in headless mode (it's noted if that's the case) due to Chrome limitations (e.g. the user-preferences
plugin), look into xvfb-run
if you still require a headless experience in these circumstances.
2.1.6 ➠ 3.1.1
2.1.6
➠ 3.1.1
Big refactor, the core is now written in TypeScript 🎉 That means out of the box type safety for fellow TS users and nice auto-completion in VSCode for JS users. Also:
addExtra
export, to patch any puppeteer compatible library with plugin functionality (chrome-aws-lambda
, etc). This also allows for multiple puppeteer instances with different plugins.The API is backwards compatible, I bumped the major version just in case I missed something. Please report any issues you might find with the new release. :)
Modular plugin framework to teach puppeteer
new tricks.
This module acts as a drop-in replacement for puppeteer
.
Allows PuppeteerExtraPlugin's to register themselves and to extend puppeteer with additional functionality.
Example:
1const puppeteer = require('puppeteer-extra') 2puppeteer.use(require('puppeteer-extra-plugin-anonymize-ua')()) 3puppeteer.use( 4 require('puppeteer-extra-plugin-font-size')({ defaultFontSize: 18 }) 5) 6;(async () => { 7 const browser = await puppeteer.launch({ headless: false }) 8 const page = await browser.newPage() 9 await page.goto('http://example.com', { waitUntil: 'domcontentloaded' }) 10 await browser.close() 11})()
plugin
PuppeteerExtraPluginReturns: this The same PuppeteerExtra
instance (for optional chaining)
The main interface to register puppeteer-extra
plugins.
Example:
1puppeteer.use(plugin1).use(plugin2)
options
Puppeteer.LaunchOptions? See puppeteer docs.Returns: Promise<Puppeteer.Browser>
The method launches a browser instance with given arguments. The browser will be closed when the parent node.js process is closed.
Augments the original puppeteer.launch
method with plugin lifecycle methods.
All registered plugins that have a beforeLaunch
method will be called
in sequence to potentially update the options
Object before launching the browser.
Example:
1const browser = await puppeteer.launch({ 2 headless: false, 3 defaultViewport: null 4})
options
Puppeteer.ConnectOptions? See puppeteer docs.Returns: Promise<Puppeteer.Browser>
Attach Puppeteer to an existing Chromium instance.
Augments the original puppeteer.connect
method with plugin lifecycle methods.
All registered plugins that have a beforeConnect
method will be called
in sequence to potentially update the options
Object before launching the browser.
options
Puppeteer.ChromeArgOptions? See puppeteer docs.The default flags that Chromium will be launched with.
Returns: string
Path where Puppeteer expects to find bundled Chromium.
options
Puppeteer.FetcherOptions? See puppeteer docs.Returns: Puppeteer.BrowserFetcher
This methods attaches Puppeteer to an existing Chromium instance.
Type: Array<PuppeteerExtraPlugin>
Get a list of all registered plugins.
name
string? Filter data by optional plugin nameCollects the exposed data
property of all registered plugins.
Will be reduced/flattened to a single array.
Can be accessed by plugins that listed the dataFromPlugins
requirement.
Implemented mainly for plugins that need data from other plugins (e.g. user-preferences
).
Type: PuppeteerExtra
The default export will behave exactly the same as the regular puppeteer (just with extra plugin functionality) and can be used as a drop-in replacement.
Behind the scenes it will try to require either puppeteer
or puppeteer-core
from the installed dependencies.
Example:
1// javascript import 2const puppeteer = require('puppeteer-extra') 3 4// typescript/es6 module import 5import puppeteer from 'puppeteer-extra' 6 7// Add plugins 8puppeteer.use(...)
puppeteer
VanillaPuppeteer Any puppeteer API-compatible puppeteer implementation or version.Returns: PuppeteerExtra A fresh PuppeteerExtra instance using the provided puppeteer
An alternative way to use puppeteer-extra
: Augments the provided puppeteer with extra plugin functionality.
This is useful in case you need multiple puppeteer instances with different plugins or to add plugins to a non-standard puppeteer package.
Example:
1// js import 2const puppeteerVanilla = require('puppeteer') 3const { addExtra } = require('puppeteer-extra') 4 5// ts/es6 import 6import puppeteerVanilla from 'puppeteer' 7import { addExtra } from 'puppeteer-extra' 8 9// Patch provided puppeteer and add plugins 10const puppeteer = addExtra(puppeteerVanilla) 11puppeteer.use(...)
Copyright © 2018 - 2023, berstend̡̲̫̹̠̖͚͓̔̄̓̐̄͛̀͘. Released under the MIT License.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 7/30 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
63 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-14
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More