ego (lite) 只是一款浏览器;ego 才是你跨设备的个人 Agent。
加入候补名单
PlaywrightPuppeteerClaude CodeMCP serversAI agents

Playwright vs Puppeteer for Claude Code: What Actually Matters

2026年8月13日8 min read
Claude robot balancing Playwright's theater masks and a Puppeteer marionette browser window in outstretched hands against a sunny mountain landscape

The short answer, before anything else: for Claude Code, pick Playwright. Its MCP server is first-party and actively maintained by Microsoft while Puppeteer's reference MCP server is deprecated on npm, and its auto-waiting gives agent-written code a lower flake rate. Puppeteer still wins Chrome-specific, screenshot-heavy scripting and codebases that already standardized on it.

For daily tasks behind your logins, ego (lite) combines what both libraries give (code-written, agent-driven control) with the logged-in sessions neither launches with: a free browser sharing your signed-in state with agents like Claude Code, which drives it by piping JavaScript through the ego-browser skill so whole workflows run outside the model's context.

Most Playwright-vs-Puppeteer articles compare them for humans. Point them at Claude Code and the question changes shape, because an agent doesn't care about your API preferences; it cares about what's maintained, what it can write reliably, and what its tools support.

What's the deciding fact for Claude Code?

If Claude Code will drive the browser through MCP tools, the ecosystem has already voted. Playwright MCP (@playwright/mcp) is published and maintained by Microsoft's Playwright team, installed with one line, documented per client. Puppeteer's reference MCP server is marked deprecated on npm, with community forks as the only continuation.

The npm page for @modelcontextprotocol/server-puppeteer showing a red deprecation banner reading This package has been deprecated, package no longer supported
Not a rumor: the @modelcontextprotocol/server-puppeteer page on npm, red banner and all. 'This package has been deprecated. Package no longer supported.' Last publish over a year ago.

A deprecated dependency at the center of an agent toolchain is a maintenance liability, and the testmuai comparison of the two stacks said exactly that: if an agent drives the browser through MCP, pick Playwright, because its server is first-party and maintained. It's rare for a versus question to have this clean an answer at one layer.

What deprecation means in practice, since the package still installs: no security patches tracked to new Chrome releases, no fixes when the MCP spec moves, and community forks whose maintenance you audit yourself. For a tool that holds a browser session on your machine, each of those is disqualifying alone.

At the MCP layer, there's no contest to write about.

What are the two ways Claude Code drives a browser?

The MCP route is only half the story, though. Claude Code is a coding agent, and a popular r/ClaudeCode thread put the other half bluntly: having Claude Code use Playwright directly, by writing automation scripts against the JavaScript API, is "vastly superior" to the MCP for many workflows, because the verbose per-step snapshots disappear and the agent just writes code.

That's the real fork for this comparison:

RouteHow it worksPlaywright or Puppeteer?
MCP toolsAgent calls browser tools step by step; page snapshots return into contextPlaywright, by forfeit: its server is maintained, Puppeteer's reference server isn't
Agent-written codeAgent writes a script with the library, runs it, reads results; nothing per-step enters contextBoth work; Playwright's auto-waiting gives agent-written code a lower flake rate (next section)

Notice the second route is also the token-efficient one: it's the same insight behind the official Playwright CLI, which cut a 114K-token MCP test run to 27K by moving execution out of the conversation. When Claude Code writes the script, your context holds code and results, not accessibility trees.

The transcripts look completely different too. An MCP session reads as forty tool calls, each trailing a page snapshot; a code session reads as one script, one run, one results block. When something breaks, the second transcript is the one you can actually scroll.

Why does auto-waiting matter more for agents?

The microsoft/playwright-mcp GitHub repository, 36.1k stars, maintained by the Playwright team with weekly releases
The maintained side of the asymmetry: microsoft/playwright-mcp, 36.1k stars, releases landing weekly. This is what first-party maintenance looks like next to the red banner above.

Here's the underrated part. Puppeteer requires explicit waiting: forget a waitForSelector({visible: true}) before a click and you've written a script that passes today and flakes Friday. Human seniors internalize this; coding agents, like juniors, omit waits under exactly the conditions that produce them: unfamiliar pages, long scripts, hurried context.

Playwright's auto-waiting closes that class structurally: every action runs actionability checks (element attached, visible, stable, enabled) before executing. An agent that writes a naive Playwright script gets correct waiting for free; the same naive Puppeteer script is a latent flake. When the code author is a model you'll prompt again tomorrow, defaults beat discipline.

The two-line version of the difference:

// Puppeteer: correct only if the agent remembers the wait
await page.waitForSelector('#submit', { visible: true })
await page.click('#submit')

// Playwright: the wait is built into the action
await page.click('#submit')

There's a debugging dividend too: fewer flaky failures means fewer rounds of Claude Code re-running and re-diagnosing its own scripts, which is where agent browser sessions quietly burn their budgets. A flake the agent writes at step 3 costs you the re-run, the re-diagnosis, and sometimes a wrong fix to code that was never broken.

Defaults are prompts you don't have to write.

When does Puppeteer still win?

Three real cases, so this doesn't read like a eulogy.

Your codebase already runs Puppeteer: Claude Code works with what's in the repo, and its training covers Puppeteer deeply; consistency beats migration for existing automation.

The task is Chrome-only and screenshot- or PDF-heavy: Puppeteer's screenshot median (276ms vs Playwright's 836ms) compounds over hundreds of captures, and its PDF pipeline is battle-tested. And minimal-dependency scripting: for a quick Chrome-only script, Puppeteer's smaller footprint is genuinely pleasant.

What shouldn't tip the decision: raw speed (timed benchmarks show wins on both sides and "neither faster overall"), or GitHub stars (94K vs 90K, effectively a tie). Both are healthy projects; only one of them is where the agent tooling ships first.

The combined route for daily tasks

Both libraries share a default that's invisible until it bites: they launch clean browsers with none of your logins. Fine for testing your own app; wrong for the daily tasks people actually hand Claude Code, like pulling numbers from dashboards or collecting listings from sites where you have accounts, where scripted auth becomes permanent maintenance.

ego (lite) is not a third library; it's an agent browser for browser automation that combines the code-writing control both libraries give with the logged-in sessions neither launches with.

Claude Code drives it the code-writing way (the route the r/ClaudeCode thread preferred), piping JavaScript through the ego-browser skill so whole workflows run outside the model's context, and it inherits every session your browser holds, working in its own Space instead of your window.

Here's what that actually looks like, not a mockup: a real ego-browser session against a live page today, task opened, page loaded, data extracted, and only the result piped back:

ego-browser nodejs <<'EOF'
const task = await egoBrowser.newTaskSpace('evidence-egobrowser-hn')
console.log({ taskSpaceId: task.id })

await task.page.goto('https://news.ycombinator.com/', { waitUntil: 'load', timeout: 20000 })
const title = await task.page.title()
const topStory = await task.page.locator('.athing .titleline > a').first().innerText()
const points = await task.page.locator('.subtext .score').first().innerText().catch(() => null)
console.log({ title, url: task.page.url(), topStory, points })
EOF
{
  "taskSpaceId": 13
}
{
  "title": "Hacker News",
  "url": "https://news.ycombinator.com/",
  "topStory": "Qwen 3.8 27B",
  "points": "412 points"
}

In our published benchmark, that execution style finished tasks in 44% fewer rounds with 35.5% fewer tool calls at 21.6% lower cost than command-at-a-time execution.

So the working split for a Claude Code user: Playwright for testing and public-page automation, Puppeteer where the repo or the screenshot pipeline says so, ego (lite) for the logged-in daily work neither was designed to hold.

Download ego (lite) for Mac or read the MCP vs CLI token measurements. Free.

FAQ

Does Claude Code work with Puppeteer at all?

Yes, well, via the code route: Claude Code writes and runs Puppeteer scripts fluently. What's gone is the maintained MCP path; the reference server-puppeteer is deprecated on npm, so tool-call-style browsing should go through Playwright MCP instead.

Should Claude Code use Playwright MCP or write Playwright code?

MCP for short exploratory sessions where you want every step visible and approvable; direct code for long or repeated workflows, where it avoids the snapshot token bill (measured runs: 89K-114K tokens over MCP vs 24K-27K over CLI-style execution) and produces a reusable script.

Is there any maintained Puppeteer MCP server?

Community forks of the deprecated reference server exist, but none carry first-party backing. If MCP is your route and you're free to choose the engine, that asymmetry is the whole answer.

Does the official Playwright CLI change this comparison?

It reinforces it. The CLI (@playwright/cli, with installable agent skills for Claude Code) is Microsoft's own answer to MCP token costs, and there's no Puppeteer equivalent with first-party backing. Every layer built for agents (MCP server, CLI, skills) now exists on the Playwright side first.

Can Claude Code mix Puppeteer and Playwright in one project?

Technically yes, and it's usually a mistake: two browser dependencies, two sets of idioms for the agent to keep straight, and double the flake surface. The exception is transition periods, where new tests land in Playwright while legacy Puppeteer scripts keep running until they earn a rewrite.

Which handles logged-in sites better with Claude Code?

Neither, natively: both start fresh profiles, so auth is scripted either way. For your own accounts, having Claude Code drive ego (lite) skips the problem, since the browser already holds your sessions and the agent starts past the login wall.