Browser Automation: Playwright vs Puppeteer vs browser-use

Table of content

Three tools dominate browser automation for AI agents. Each solves different problems.

Quick Comparison

ToolLanguageBest ForAI-Native
PlaywrightJS/Python/C#Testing, scrapingNo
PuppeteerJavaScriptChrome automationNo
browser-usePythonAI agentsYes

Playwright

Microsoft’s testing framework. Supports Chromium, WebKit, and Firefox from one API.

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

// Wait for element, then click
await page.click('text=Login');
await page.fill('#email', 'user@example.com');
await page.screenshot({ path: 'screenshot.png' });

await browser.close();

Strengths:

Weaknesses:

Puppeteer

Google’s Chrome DevTools Protocol wrapper. The original headless browser tool.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

// Evaluate JS in browser context
const title = await page.evaluate(() => document.title);
console.log(title);

await page.pdf({ path: 'page.pdf' });
await browser.close();

Strengths:

Weaknesses:

browser-use

Python library built for AI agents. 77k+ GitHub stars. Uses vision models to understand pages.

from browser_use import Agent
from langchain_openai import ChatOpenAI

agent = Agent(
    task="Go to google.com and search for 'browser automation'",
    llm=ChatOpenAI(model="gpt-4o"),
)

await agent.run()

Strengths:

Weaknesses:

When to Use Each

Playwright: You know the page structure. You need reliability and speed. Testing or scraping with predictable selectors.

Puppeteer: Chrome-only is fine. You want minimal dependencies. PDF generation matters.

browser-use: Your agent needs to handle arbitrary websites. You can’t hardcode selectors. Speed matters less than flexibility.

Hybrid Approach

Combine them. Use browser-use for discovery, then extract selectors for Playwright:

# First: agent figures out the flow
agent = Agent(task="Find the login form and note the selectors")
result = await agent.run()

# Later: Playwright uses those selectors directly
await page.fill(result.selectors['email'], email)
await page.fill(result.selectors['password'], password)

This gives you AI flexibility during development and deterministic speed in production.

What You Can Steal

From Playwright:

From Puppeteer:

From browser-use:

Next: Building Browser Agents