Guides

Playwright vs Selenium vs Puppeteer: Which To Use?

In this article, we'll look at the most popular browser automation tools. We'll compare their use cases, performance, browser support, and language support.

Nik Tomazic

Playwright, Selenium, and Puppeteer are the three most popular browser automation tools. They can be used for end-to-end testing, web scraping, screenshot generation, and increasingly to enable AI agents to use the browser.

While Playwright and Puppeteer are architecturally similar, Selenium is an entirely different beast. In this article, we'll cover each tool's history, pros and cons, and main use cases. Additionally, we'll introduce Browser Use, an AI successor to traditional browser automation.

TL;DR

If you need...Use
Test automationPlaywright
Simple, Chromium-focused automationPuppeteer
Legacy browser supportSelenium
Agentic workflows / sites that change oftenBrowser Use

Selenium

Selenium is a pioneering framework for browser automation. It was started by Jason Huggins in 2004. Over time, the team behind Selenium developed multiple browser automation tools, including:

  • Selenium IDE (2006) -- a browser extension that lets you record, edit, and play back interactions with websites and web apps.
  • Selenium Grid (2008) -- allows running web tests in parallel across multiple machines, browsers, and operating systems at the same time.
  • Selenium WebDriver (2011) -- formed the basis for the W3C WebDriver standard, which became a W3C Recommendation in 2018. Most major web browsers support it, including Chrome, Firefox, Safari, and Edge.

The Selenium WebDriver communication protocol looks something like this:

Selenium Communication Architecture

In 2020, Selenium began contributing to the W3C's WebDriver BiDi standard, which fills some gaps of the classic WebDriver and is intended to replace it in the future.

Selenium's main use cases include automated UI testing, regression testing, cross-browser testing, and web scraping.

The framework's main advantages are its W3C standard status, mature & extensive ecosystem, and support for legacy browsers. On top of that, the framework supports multiple programming languages, including Java, Python, C#, JavaScript, and Ruby.

Selenium's main downsides are that it doesn't provide the best developer experience (difficult to set up, lots of boilerplate code), adds performance overhead (classic WebDriver uses HTTP), and isn't the most elegant solution for modern web apps (e.g. SPAs).

To extract a page's <h1> tag with Selenium, you can use a script like this:

// selenium.js
 
const { Builder, By, until } = require("selenium-webdriver");
 
(async () => {
  // Launch a new Chrome browser instance (via ChromeDriver)
  const driver = await new Builder().forBrowser("chrome").build();
 
  try {
    // Navigate to the target page
    await driver.get("https://browser-use.com/");
 
    // Wait for h1 to appear in the DOM and for it to render
    const h1 = await driver.wait(until.elementLocated(By.css("h1")), 10000);
    await driver.wait(until.elementIsVisible(h1), 10000);
 
    // Extract the visible text and log it
    const text = await h1.getText();
    console.log("H1:", text);
  } finally {
    // Close the browser (even if an error was raised)
    await driver.quit();
  }
})();

Puppeteer

Puppeteer is a Node.js library for browser automation that Google created in 2017. The library was released right after Chrome shipped its headless mode. Unlike Selenium, which uses WebDriver, Puppeteer uses the Chrome DevTools Protocol (CDP) for Chrome and BiDi for Firefox automation.

Chrome DevTools Protocol is a low-level interface for inspecting and controlling the Chromium-based browsers. Compared with WebDriver, it is significantly faster because it uses a persistent WebSocket connection instead of HTTP requests. Moreover, it enables bidirectional communication.

Puppeteer Communication Architecture

BiDi is architecturally similar to CDP but vendor-agnostic.

The library is mostly used for scraping both traditional websites and SPAs, taking screenshots, PDF generation, and other browser automation tasks.

Puppeteer's main advantages include its performance, lightweightness, and its ability to leverage Chrome/Chromium-specific capabilities. These include network interception, browser debugging, performance monitoring, and device emulation.

On the other hand, Puppeteer also has a few disadvantages. Firstly, it is Chromium-centric (BiDi has a reduced API surface), has a smaller ecosystem than Selenium, and only supports JavaScript and TypeScript.

Here's the same exact script to extract the page heading in Puppeteer:

// puppeteer.js
 
const puppeteer = require("puppeteer");
 
(async () => {
    // Launch a new Chrome browser instance
    const browser = await puppeteer.launch();
 
    try {
        const page = await browser.newPage();
 
        // Navigate to the target page
        await page.goto("https://browser-use.com/");
 
        // Wait for h1 to appear in the DOM and for it to render
        const h1 = await page.waitForSelector("h1", {
            visible: true,
            timeout: 10000,
        });
 
        // Extract the visible text and log it
        const text = await h1.evaluate((el) => el.textContent);
        console.log("H1:", text);
    } finally {
        // Close the browser (even if an error was raised)
        await browser.close();
    }
})();

Playwright

Playwright is a browser automation framework developed at Microsoft and open-sourced in January 2020. It was created by the same group of engineers who had previously worked on Puppeteer.

The framework adopted Puppeteer's best ideas and fixed its biggest gaps. It added support for Firefox and WebKit (via Playwright-specific browser builds), support for multiple programming languages (Python, .NET, and Java). It introduced auto-waits, browser contexts, codegen, trace viewer, and other powerful tooling.

Playwright's communication works similarly to Puppeteer. It uses CDP for Chromium-based browsers, and custom protocols for Firefox and WebKit:

Playwright Communication Architecture

The framework is most commonly used for test automation. This is mainly because of its built-in test runner and its ability to write clean, concise, maintainable tests. Other than that, the framework can also be used for scraping, and it has been increasingly adopted by AI browser agents.

Its downsides are fewer, but they exist. Firefox and WebKit are Playwright-specific builds rather than the browsers your users actually run; it doesn't support legacy browsers, and its ecosystem is younger and smaller than Selenium's. It is also somewhat opinionated.

Finally, the same heading-fetching script in Playwright:

// playwright.js
 
const { chromium } = require("playwright");
 
(async () => {
    // Launch a new Chrome browser instance
    const browser = await chromium.launch();
 
    try {
        const page = await browser.newPage();
 
        // Navigate to the target page
        await page.goto("https://browser-use.com/");
 
        // Locator auto-waits for the element to appear when you act on it
        const h1 = page.locator("h1").first();
 
        // Extract the visible text and log it
        const text = await h1.textContent();
        console.log("H1:", text);
    } finally {
        // Close the browser (even if an error was raised)
        await browser.close();
    }
})();

Browser Use

To automate a browser with traditional browser automation tools, you must describe the whole process in code. Browser Use, an open-source library for AI browser automation started in 2024, inverts that. Instead of describing the process in code, you describe the goal using natural language.

For example, you can provide these prompts to Browser Use agents:

  • Book me the fastest flight from Bali to San Francisco on the 18th of September.
  • Go to Wikipedia's page for the world's countries and extract the top 10 biggest countries' name, area_km2 and population as valid JSON.
  • Search for the latest news about NVIDIA and summarize the three biggest stories.

To make it work, the library extracts the DOM into an indexed, text-like representation. It then uses an LLM to reason over it and determine how to perform the task. Historically, Browser Use used Playwright, but later migrated to raw CDP for faster, more capable automation.

Browser Use Communication Architecture

Browser Use's main advantages are speed to a working automation, resilience to DOM changes that would break a hardcoded selector, and ease of use. Additionally, by opting into Browser Use Cloud you get built-in stealth and protection against bot detection.

The downsides are the same as those of every other AI-driven automation tool. Runs are non-deterministic (the same prompt can take different paths), each step costs an LLM call, and failures are harder to trace and debug.

Since Browser Use would be overkill for extracting an <h1>, let's demonstrate how to fetch top 5 HackerNews stories:

# browser-use.py
 
import asyncio
from browser_use import Agent, ChatAnthropic
from pydantic import BaseModel
 
 
# Define the shape of a single story
class Story(BaseModel):
    title: str
    points: int
 
 
# Wrap the stories in a list so the agent returns all 5 at once
class Stories(BaseModel):
    stories: list[Story]
 
 
async def main() -> None:
    # Describe the goal in natural language instead of in code
    agent = Agent(
        task="""
        Find the top 5 HN stories.
        Return only {"stories": [{"title": "..." , "points": 0}, ...]}.
        """,
        llm=ChatAnthropic(model="claude-sonnet-5"),
        # Force the agent's final output to match the schema above
        output_model_schema=Stories,
    )
 
    # Let the agent navigate and extract on its own
    history = await agent.run()
 
    # Parse the final result and print each story
    stories = Stories.model_validate_json(history.final_result() or "{}")
    for story in stories.stories:
        print(story)
 
 
if __name__ == "__main__":
    asyncio.run(main())

Conclusion

In this article, we've looked at the most popular browser automation libraries.

As a rule of thumb, use Playwright for test automation because of its extensive tooling. Puppeteer for simple Chrome automations, Selenium if you require legacy browser support, and Browser Use for agentic workflows or when working with websites that change frequently.

Finally, I've summarized the differences down below:

SeleniumPuppeteerPlaywrightBrowser Use
Main useCross-browser testingScraping, screenshots, PDFsTest automationAgentic workflows
BrowsersAll major + legacyChrome, FirefoxChrome, Firefox, WebKitChrome
LanguagesJava, Python, C#, JS, RubyJS, TSJS, TS, Python, .NET, JavaPython
ProtocolWebDriverCDP (Chrome), BiDi (Firefox)CDP + customCDP
ProsW3C standard, mature ecosystemFast, lightweight, deep Chrome accessAuto-waits, test runner, multi-browser, dev toolingFastest to build, resilient to DOM changes
ConsBoilerplate, slow, weak with SPAsNo WebKit, JS/TS-onlyPatched browsers, younger ecosystemNon-deterministic, LLM cost, harder to debug

Published