If you’ve ever tried to deploy a Playwright script to Vercel Functions, you probably ran into an error that looked something like this:
Error: Failed to launch browser. Chromium not found.
That’s because serverless environments like Vercel aren’t designed to run full headless browsers. The Chromium binary Playwright tries to launch doesn’t exist in Vercel’s sandbox: and even if it did, the cold start times and memory limits would make it unusable for anything serious.
So does that mean you can’t run Playwright on Vercel?
Not exactly.You can: but you have to think about it differently.
In this post, we’ll walk through how to run Playwright scripts on Vercel by using a hosted browser from Kernel, and connecting to it remotely over CDP (Chrome DevTools Protocol).
The Problem: Playwright Needs a Real Browser
Playwright is a powerful automation framework built by Microsoft. It can simulate real user interactions, run tests, scrape data, or capture screenshots across Chrome, Firefox, and Safari.
When you use it locally, Playwright spins up a browser with something like this:
const browser = await playwright.chromium.launch();
That line is where things break in Vercel.
Vercel’s functions run in lightweight, sandboxed Linux containers with limited memory and no access to system-level binaries like chromium. These environments are perfect for fast API routes or SSR rendering, but not for CPU-heavy tasks like browser automation.
You’ll hit errors like:
- “Chromium not found”
- “Cannot launch browser: missing dependencies”
- “Function exceeded memory limit”
The result: your Playwright script works locally, but not once you deploy to the cloud.

Can You Run Playwright On Vercel?
The Workaround: Separate the Script From the Browser
The trick is to decouple the browser runtime from the script logic.
Instead of trying to run the browser inside Vercel, you can run the browser remotely, somewhere that’s built for it, and just connect to it from your script.
That’s where Kernel comes in.
Meet Kernel: The Hosted Browser Cloud
Kernel provides a cloud API for running browsers at scale. It spins up real Chrome or Chromium instances in isolated environments and exposes each one via a CDP WebSocket endpoint.
This means you can do things like:
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
Instead of launching a browser with chromium.launch(), you connect to a remote one that’s already running in Kernel’s cloud.
It’s like using ssh to access a remote server, but for browsers.
The benefits:
- No need to package or upload binaries
- No startup lag: browsers are ready instantly
- Works from any environment (Vercel, AWS Lambda, etc.)
- Kernel handles scaling, timeouts, and cleanup
How It Works: Under the Hood
Here’s what happens step-by-step:
- 1Your Vercel Function runs your Playwright script.
- 2The script calls
kernel.browsers.create(). - 3Kernel spins up a new browser in the cloud and returns its CDP WebSocket URL.
- 4Playwright connects to that URL using
chromium.connectOverCDP(). - 5From there, your script behaves exactly like normal Playwright code: but it’s driving a remote browser.
That means you can still:
- Navigate to pages (
page.goto(url)) - Click elements, type, and evaluate scripts
- Take screenshots or extract data
- Run tests or collect metrics
The only difference is: the browser isn’t local, it’s remote.
Example: Running Playwright on Vercel with Kernel
Let’s make this concrete.
Here’s an example api/run-playwright.js you could deploy on Vercel:
import { chromium } from 'playwright';
import { Kernel } from '@onkernel/sdk';
export default async function handler(req, res) {
const kernel = new Kernel();
// 1. Start a browser in Kernel’s cloud
const kernelBrowser = await kernel.browsers.create();
// 2. Connect Playwright to it
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
try {
// 3. Use Playwright as usual
const context = browser.contexts()[0] || await browser.newContext();
const page = context.pages()[0] || await context.newPage();
await page.goto('https://www.google.com');
const title = await page.title();
res.status(200).json({ title });
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message });
} finally {
// 4. Clean up
await browser.close();
await kernel.browsers.deleteByID(kernelBrowser.session_id);
}
}
Deploy that to Vercel, hit /api/run-playwright, and you’ll get a JSON response like:
{ "title": "Google" }
No binary errors. No missing Chromium. No Docker gymnastics.
Just pure, serverless Playwright.
Why This Pattern Works So Well
The “remote browser” pattern solves three major headaches of serverless environments:
1. Binary Limitations
Vercel doesn’t ship with Chrome. Kernel does.
2. Cold Start Latency
Launching Chrome can take 1–2 seconds locally. Kernel’s prewarmed browsers start instantly.
3. Resource Isolation
Kernel runs browsers in containers purpose-built for automation, with predictable memory and CPU allocation, so they don’t get throttled like they would on a lambda.
This pattern effectively lets you embed Playwright anywhere, even in tiny serverless runtimes.
When to Use This Approach
This remote-browser approach is ideal for:
- Serverless scraping or automation Run Playwright tasks from APIs, edge functions, or cloud jobs without managing infrastructure.
- Web testing and monitoring Trigger end-to-end tests on real browsers without maintaining CI runners.
- Data enrichment and lead generation Use Playwright to visit pages, extract info, or verify content programmatically.
- Browser-based AI workflows Combine Kernel + LLMs to browse, click, and collect data automatically.
Essentially, anywhere you’d normally use Playwright locally, but want to run it from a serverless environment, this setup unlocks it.
When Not to Use It
There are a few cases where self-hosting Playwright still makes sense:
- You’re dealing with sensitive data and require on-prem environments
- You already have an internal Playwright cluster or grid
- You need custom Chromium flags or extensions
In those cases, a hosted approach might not be needed, but it could depend on the context.
Performance and Pricing Considerations
One of the biggest wins of this architecture is scalability. Because your Vercel function is lightweight (it only runs JavaScript logic, not a browser) you pay for milliseconds, not megabytes.
Kernel, meanwhile, scales your browser sessions independently. You can run one or one thousand browsers concurrently without worrying about server limits or concurrency caps on Vercel.
In short:
- Vercel = fast control plane (cheap)
- Kernel = powerful browser engine (scalable)
It’s the same principle that powers modern APIs: offloading heavy compute to specialized infrastructure.
Putting It All Together
Here’s the mental model:

Playwright, Vercel, & Hosting
Your script doesn’t know (or care) that the browser lives elsewhere: Playwright’s API is identical.
So whether you’re scraping, testing, or generating screenshots, the workflow feels the same as always.
Troubleshooting Tips
If you’re trying this setup for the first time:
- Double-check your Playwright import: Use import { chromium } from 'playwright' (not @playwright/test).
- Close your browser session: Always call await kernel.browsers.deleteByID() to free resources.
- Log connection errors: If connectOverCDP fails, print kernelBrowser.cdp_ws_url to verify your connection.
- Use environment variables: Store your Kernel API key in VERCEL_ENV or .env.local, not inline.
Final Thoughts
So, can you run Playwright on Vercel?
Yes… just not the way you expect.
Instead of forcing a browser to live inside a serverless function, you let Vercel run the code and let Kernel handle the browser.
They talk over CDP like old friends.
The result is the best of both worlds:
- Full browser automation power
- Instant scalability
- No binary or setup headaches
Once you start thinking this way: separating browser orchestration from browser execution, the possibilities open wide.
You can automate the web from anywhere: edge runtimes, AI workflows, cron jobs, or APIs.
In other words:
You can run Playwright on Vercel: as long as your browser lives in the cloud. 🌩️
Oh btw.. it’s worth mentioning too that we recently launched an official Vercel integration! Here’s a link to the Kernel <> Vercel integration too: https://vercel.com/marketplace/kernel. Feel free to check it out :)
