Puppeteer - Node.js library for controlling headless Chrome, Chromium, and Firefox

repository·main·Indexed Apr 15, 2026

https://github.com/puppeteer/puppeteer

Puppeteer is a Node.js library providing a high-level API to control headless Chrome, Chromium, and Firefox browsers over the DevTools Protocol. It supports web scraping, end-to-end testing, and generating screenshots or PDFs. The library offers a bundled Chrome installation and a library-only mode via puppeteer-core, with browser binary management handled by the @puppeteer/browsers package. Features include programmatic browser installation and launching, CLI tools for managing browser binaries, CDPSession for raw DevTools Protocol access, and options to connect to existing browser instances. The repository includes Docker images for containerized execution and examples for common use cases.

Tokens
20K
Snippets
46
Records
70
Agent score
100%

What's inside puppeteer

  1. Core features of Puppeteer

    main

    Puppeteer allows you to automate almost any manual browser interaction. Key capabilities include:

    • Automation: Automate form submissions, UI testing, and keyboard/mouse input.
    • Testing: Create automated testing environments using modern JavaScript and browser features.
    • Performance: Capture timeline traces to diagnose site performance.
    • Extensions: Test Chrome Extensions.
    • Media Generation: Generate screenshots and PDFs of web pages.
    • Web Crawling & SSR: Crawl Single-Page Applications (SPAs) and generate pre-rendered content (Server-Side Rendering).
  2. What is bidi/core?

    main

    bidi/core is a low-level abstraction layer designed to sit above the WebDriver BiDi transport. It transforms the flat WebDriver BiDi API into a structured, object-oriented API.

    Key features include:

    • Object-Oriented Semantics: It provides structured representations of WebDriver BiDi resources.
    • Event Orchestration: It automatically manages the correct sequence of WebDriver BiDi events to ensure semantic correctness.
    • Spec Compliance: It prioritizes strict adherence to the WebDriver BiDi specification over Puppeteer-specific requirements to ensure predictable behavior and easier bug identification.
  3. Use custom providers for browser downloads

    main

    You can provide an array of BrowserProvider implementations via the providers property in InstallOptions to use alternative download sources.

    Important Considerations:

    • Chaining: Multiple providers can be chained and will be tried in the order provided. The default provider is automatically added as the final fallback.
    • Support: Custom providers are NOT officially supported by Puppeteer.
    • Responsibility: If you use custom providers, you are responsible for version compatibility, binary archive structure, feature integration (like browser launch), and testing. Puppeteer only guarantees compatibility with its default binaries.
  4. Use the EventEmitter class to listen to Puppeteer events

    main

    Many Puppeteer classes extend the EventEmitter class, which allows you to listen to specific events fired by those objects and execute code in response.

    To interact with events, you will primarily use:

    • on(type, handler): Binds a listener to fire every time a specific event occurs.
    • once(type, handler): Binds a listener that fires only the first time the event occurs, then automatically removes itself.
    • off(type, handler): Unbinds a previously registered listener.
    • removeAllListeners(type): Removes all listeners for a specific event type, or all listeners if no type is provided.
    • listenerCount(type): Returns the number of active listeners for a specific event.

    Note: The EventEmitter constructor is internal. You should not call the constructor directly or attempt to create your own subclasses that extend EventEmitter in third-party code.

    // Example pattern for using an EventEmitter-based class
    page.on('request', request => {
      console.log('Request sent to:', request.url());
    });
    
    page.once('close', () => {
      console.log('Page closed');
    });
  5. Restrict site access with URL blocklist and allowlist

    main

    Puppeteer provides mechanisms to restrict browser access to specific sites to prevent unauthorized navigation:

    • URL Blocklist: Implemented in version 24.42.0, this allows you to restrict access to unauthorized sites.
    • Allowlist: Implemented in version 24.43.0, providing a way to permit only specific URLs.
  6. Understand the HandleOr<T> type

    main

    The HandleOr<T> type is a union type used in Puppeteer to represent a value that can be one of three things: a HandleFor<T>, a JSHandle<T>, or the raw value T itself. This allows Puppeteer APIs to be flexible, accepting either a direct value or a reference (handle) to an object within the browser context.

    export type HandleOr<T> = HandleFor<T> | JSHandle<T> | T;
  7. Manage a virtual keyboard with the Keyboard class

    main

    The Keyboard class provides an API for managing a virtual keyboard in Puppeteer. The primary high-level method is Keyboard.type(), which takes raw characters and automatically generates the necessary keydown, keypress/input, and keyup events for each character.

    Important Limitations:

    • macOS Shortcuts: Keyboard shortcuts like ⌘ A (Select All) do not work on macOS.
    • Extending the class: The Keyboard constructor is internal. Do not attempt to call the constructor directly or create subclasses that extend the Keyboard class.
    // High-level usage
    await page.keyboard.type('Hello World!');
  8. Use Cooperative Intercept Mode with priorities

    main

    Cooperative Intercept Mode allows multiple handlers to 'vote' on how a request should be resolved. Instead of the first handler winning, the resolution with the highest priority wins.

    Rules of Cooperative Intercept Mode:

    • Activation: All handlers must provide a numeric priority argument to abort(), continue(), or respond(). If any handler omits the priority, the system reverts to Legacy Mode (immediate resolution by the first handler).
    • Winning Logic: The highest priority wins. In the event of a tie, the precedence is: abort > respond > continue.
    • Standard Priority: Use 0 or DEFAULT_INTERCEPT_RESOLUTION_PRIORITY (from HTTPRequest) for standard behavior. This allows for graceful coexistence.
    • Async Behavior: Async handlers finish before the final intercept resolution is determined.

    Comparison Table

    ModeRequirementBehavior
    Legacy ModeAny handler omits priorityFirst handler to call a resolution method wins immediately.
    Cooperative ModeAll handlers provide priorityAll handlers run; the highest priority resolution wins.
    // Cooperative Intercept Mode Example
    page.setRequestInterception(true);
    
    page.on('request', request => {
      if (request.isInterceptResolutionHandled()) return;
      // Votes to abort at priority 0
      request.abort('failed', 0);
    });
    
    page.on('request', request => {
      if (request.isInterceptResolutionHandled()) return;
      // Votes to continue at priority 5. This wins because 5 > 0.
      request.continue(request.continueRequestOverrides(), 5);
    });
  9. Choose between puppeteer and puppeteer-core

    main

    Puppeteer provides two distinct packages depending on your use case:

    puppeteer (The Product)

    Use this for standard browser automation. It is a high-level package that automatically downloads a compatible version of Chrome and provides reasonable defaults for automation workflows.

    puppeteer-core (The Library)

    Use this if you want to manage browsers yourself or connect to a remote browser. It is a lightweight library that does not download Chrome.

    When to use puppeteer-core:

    • Connecting to a remote browser via puppeteer.connect.
    • Managing your own browser instances.
    • When using an existing browser installation.

    Note: If you use puppeteer-core, you must provide an executablePath or channel to puppeteer.launch, and you must change your import statement.

    import puppeteer from 'puppeteer-core';
  10. Use puppeteer-core for lightweight installations

    main
    Starting from version 18.2.0, Puppeteer was split into two packages: puppeteer (which includes a bundled version of Chromium) and puppeteer-core (which does not include a browser and requires you to provide one). Use puppeteer-core if you want to connect to an existing browser installation or manage your own browser binaries to reduce package size.
  11. Configure Chrome Linux Sandbox

    main

    If Chrome crashes with No usable sandbox!, it means the host environment is not configured for sandboxing.

    Warning: Running with --no-sandbox is strongly discouraged for security reasons.

    You can use the chrome_sandbox executable provided in the Puppeteer cache. You must set its ownership to root and permissions to 4755, then point to it using the CHROME_DEVEL_SANDBOX environment variable.

    # Example setup for setuid sandbox
    cd ~/.cache/puppeteer/chrome/linux-<version>/chrome-linux64/
    sudo chown root:root chrome_sandbox
    sudo chmod 4755 chrome_sandbox
    
    # Export the variable
    export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox