Documentation Index
Fetch the complete documentation index at: https://mintlify.com/vercel-labs/agent-browser/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Agent Browser can run in serverless environments by using lightweight Chromium builds and the programmatic API. The bundled Chromium (~684MB) is too large for most serverless platforms, so you’ll need to use optimized alternatives like @sparticuz/chromium (~50MB).
Quick Start
For serverless deployment, use the BrowserManager class directly and provide a custom executablePath:
import chromium from '@sparticuz/chromium';
import { BrowserManager } from 'agent-browser';
export async function handler() {
const browser = new BrowserManager();
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
});
// Use browser API
await browser.navigate('https://example.com');
const { tree, refs } = await browser.getSnapshot();
await browser.close();
return { statusCode: 200, body: tree };
}
Vercel
Deploy as a Vercel Function with @sparticuz/chromium.
Installation:
npm install agent-browser @sparticuz/chromium
Example API Route (api/screenshot.ts):
import type { VercelRequest, VercelResponse } from '@vercel/node';
import chromium from '@sparticuz/chromium';
import { BrowserManager } from 'agent-browser';
export default async function handler(
req: VercelRequest,
res: VercelResponse
) {
const { url } = req.query;
if (!url || typeof url !== 'string') {
return res.status(400).json({ error: 'Missing url parameter' });
}
const browser = new BrowserManager();
try {
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
});
await browser.navigate(url);
const page = browser.getPage();
const screenshot = await page.screenshot({ type: 'png' });
res.setHeader('Content-Type', 'image/png');
res.send(screenshot);
} catch (error) {
console.error('Screenshot failed:', error);
res.status(500).json({ error: 'Screenshot failed' });
} finally {
if (browser.isLaunched()) {
await browser.close();
}
}
}
vercel.json configuration:
{
"functions": {
"api/**/*.ts": {
"memory": 3008,
"maxDuration": 30
}
}
}
Notes:
- Increase memory to at least 3008 MB for Chromium
- Increase
maxDuration if operations take longer than 10s
- Cold starts can take 5-10 seconds
AWS Lambda
Deploy using Lambda Functions with @sparticuz/chromium.
Installation:
npm install agent-browser @sparticuz/chromium
Lambda Handler (index.ts):
import chromium from '@sparticuz/chromium';
import { BrowserManager } from 'agent-browser';
import type { APIGatewayProxyHandler } from 'aws-lambda';
export const handler: APIGatewayProxyHandler = async (event) => {
const url = event.queryStringParameters?.url;
if (!url) {
return {
statusCode: 400,
body: JSON.stringify({ error: 'Missing url parameter' }),
};
}
const browser = new BrowserManager();
try {
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
args: chromium.args,
});
await browser.navigate(url);
const { tree, refs } = await browser.getSnapshot();
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ snapshot: tree, refs }),
};
} catch (error) {
console.error('Browser operation failed:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Browser operation failed' }),
};
} finally {
if (browser.isLaunched()) {
await browser.close();
}
}
};
Configuration (serverless.yml or SAM template):
functions:
browserAutomation:
handler: index.handler
timeout: 30
memorySize: 3008
environment:
NODE_ENV: production
Notes:
- Set memory to at least 3008 MB
- Set timeout to at least 30 seconds
- Lambda’s
/tmp directory has 512 MB limit; Chromium uses it for downloads and caching
@sparticuz/chromium is optimized for Lambda and includes necessary shared libraries
AWS Lambda with Docker
For more control, use a Lambda container image:
Dockerfile:
FROM public.ecr.aws/lambda/nodejs:18
# Install Chromium dependencies
RUN yum install -y \
atk \
cups-libs \
gtk3 \
libXcomposite \
libXcursor \
libXdamage \
libXext \
libXi \
libXrandr \
libXScrnSaver \
libXtst \
pango \
alsa-lib \
&& yum clean all
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --production
# Install Chromium
RUN npx agent-browser install
# Copy application code
COPY index.ts ./
CMD ["index.handler"]
Build and deploy:
docker build -t agent-browser-lambda .
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker tag agent-browser-lambda:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/agent-browser-lambda:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/agent-browser-lambda:latest
Google Cloud Functions
Installation:
npm install agent-browser @sparticuz/chromium
Function Handler (index.ts):
import type { HttpFunction } from '@google-cloud/functions-framework';
import chromium from '@sparticuz/chromium';
import { BrowserManager } from 'agent-browser';
export const browserAutomation: HttpFunction = async (req, res) => {
const { url } = req.query;
if (!url || typeof url !== 'string') {
res.status(400).send({ error: 'Missing url parameter' });
return;
}
const browser = new BrowserManager();
try {
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
});
await browser.navigate(url);
const page = browser.getPage();
const title = await page.title();
res.status(200).json({ url, title });
} catch (error) {
console.error('Browser operation failed:', error);
res.status(500).send({ error: 'Browser operation failed' });
} finally {
if (browser.isLaunched()) {
await browser.close();
}
}
};
Deploy:
gcloud functions deploy browserAutomation \
--runtime nodejs18 \
--trigger-http \
--allow-unauthenticated \
--memory 2048MB \
--timeout 60s
Testing Serverless Setup Locally
Before deploying, test your serverless setup locally to verify @sparticuz/chromium integration:
// test/serverless.test.ts
import { describe, it, expect, afterAll } from 'vitest';
import { BrowserManager } from '../src/browser.js';
import * as os from 'os';
const isLinux = os.platform() === 'linux';
// @sparticuz/chromium only works on Linux
const canRunTest = await (async () => {
if (!isLinux) return false;
try {
await import('@sparticuz/chromium');
return true;
} catch {
return false;
}
})();
describe.skipIf(!canRunTest)('Serverless Chromium Integration', () => {
let browser: BrowserManager;
let chromiumPath: string;
it('should get executable path from @sparticuz/chromium', async () => {
const chromium = await import('@sparticuz/chromium');
chromiumPath = await chromium.default.executablePath();
expect(chromiumPath).toBeTruthy();
});
it('should launch browser with custom executablePath', async () => {
const chromium = await import('@sparticuz/chromium');
chromiumPath = await chromium.default.executablePath();
browser = new BrowserManager();
await browser.launch({
headless: true,
executablePath: chromiumPath,
});
expect(browser.isLaunched()).toBe(true);
});
it('should navigate and get page title', async () => {
const page = browser.getPage();
await page.goto('https://example.com');
const title = await page.title();
expect(title).toBe('Example Domain');
});
it('should take snapshot with refs', async () => {
const { tree, refs } = await browser.getSnapshot();
expect(tree).toContain('Example Domain');
expect(Object.keys(refs).length).toBeGreaterThan(0);
});
afterAll(async () => {
if (browser?.isLaunched()) {
await browser.close();
}
});
});
See test/serverless.test.ts in the source code for a complete example.
Reduce Cold Start Time
- Use deployment packages: Pre-bundle dependencies to reduce cold start
- Minimize dependencies: Only include what you need
- Use provisioned concurrency (AWS Lambda) for zero cold starts
- Keep functions warm with periodic invocations
Memory and CPU Allocation
Chromium requires significant resources:
- Minimum: 1024 MB memory (will be slow)
- Recommended: 2048-3008 MB memory for better performance
- CPU: Scales with memory on most platforms
Reuse Browser Instances
Warning: Reusing browser instances across invocations can cause memory leaks and stale state.
Safe approach:
let browser: BrowserManager | null = null;
export async function handler(event: any) {
try {
// Launch fresh browser for each invocation
browser = new BrowserManager();
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
});
// Use browser
await browser.navigate(event.url);
const result = await browser.getSnapshot();
return { statusCode: 200, body: JSON.stringify(result) };
} finally {
// Always close browser
if (browser?.isLaunched()) {
await browser.close();
}
browser = null;
}
}
Alternatives to @sparticuz/chromium
chrome-aws-lambda
Older alternative, less maintained:
import chromium from 'chrome-aws-lambda';
import { BrowserManager } from 'agent-browser';
const browser = new BrowserManager();
await browser.launch({
executablePath: await chromium.executablePath,
args: chromium.args,
headless: chromium.headless,
});
System Chrome/Chromium
If your serverless environment has Chrome/Chromium pre-installed:
import { BrowserManager } from 'agent-browser';
const browser = new BrowserManager();
await browser.launch({
executablePath: '/usr/bin/chromium-browser',
headless: true,
});
Cloud Browser Services
For production deployments, consider cloud browser services instead of running Chromium in serverless functions:
Browserbase
export BROWSERBASE_API_KEY="your-api-key"
export BROWSERBASE_PROJECT_ID="your-project-id"
export AGENT_BROWSER_PROVIDER=browserbase
agent-browser open https://example.com
See Browserbase integration for details.
Browser Use
export BROWSER_USE_API_KEY="your-api-key"
export AGENT_BROWSER_PROVIDER=browseruse
agent-browser open https://example.com
See Browser Use integration for details.
Kernel
export KERNEL_API_KEY="your-api-key"
export AGENT_BROWSER_PROVIDER=kernel
agent-browser open https://example.com
See Kernel integration for details.
Environment Variables
Key environment variables for serverless deployment:
| Variable | Description |
|---|
AGENT_BROWSER_EXECUTABLE_PATH | Path to Chromium binary |
AGENT_BROWSER_DEFAULT_TIMEOUT | Playwright timeout in ms (default: 25000) |
AGENT_BROWSER_PROVIDER | Cloud browser provider (browserbase, browseruse, kernel) |
NODE_ENV | Set to production for optimizations |
Troubleshooting
”Failed to launch browser” errors
Ensure:
- Memory is sufficient (at least 1024 MB, recommended 2048+ MB)
- Timeout is adequate (at least 30 seconds)
- executablePath is correct:
const path = await chromium.executablePath();
console.log('Chromium path:', path);
Missing shared libraries
@sparticuz/chromium includes necessary libraries for Lambda. For other platforms, install system dependencies:
# Debian/Ubuntu
apt-get install -y \
libnss3 libxss1 libasound2 libatk-bridge2.0-0 \
libgtk-3-0 libgbm1
# Alpine
apk add --no-cache \
chromium nss freetype harfbuzz ca-certificates ttf-freefont
Timeout on first invocation
Cold starts can take 5-10 seconds. Increase function timeout to at least 30 seconds.
Out of memory errors
Increase function memory allocation or use cloud browser services instead.
See Troubleshooting for more common issues.