> ## 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.

# Serverless Deployment

> Deploy Agent Browser to serverless environments like Vercel, AWS Lambda, and more

## 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`:

```typescript theme={null}
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 };
}
```

## Platform-Specific Guides

### Vercel

Deploy as a Vercel Function with `@sparticuz/chromium`.

**Installation:**

```bash theme={null}
npm install agent-browser @sparticuz/chromium
```

**Example API Route** (`api/screenshot.ts`):

```typescript theme={null}
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:**

```json theme={null}
{
  "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:**

```bash theme={null}
npm install agent-browser @sparticuz/chromium
```

**Lambda Handler** (`index.ts`):

```typescript theme={null}
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):**

```yaml theme={null}
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:**

```dockerfile theme={null}
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:**

```bash theme={null}
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:**

```bash theme={null}
npm install agent-browser @sparticuz/chromium
```

**Function Handler** (`index.ts`):

```typescript theme={null}
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:**

```bash theme={null}
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:

```typescript theme={null}
// 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.

## Performance Optimization

### Reduce Cold Start Time

1. **Use deployment packages:** Pre-bundle dependencies to reduce cold start
2. **Minimize dependencies:** Only include what you need
3. **Use provisioned concurrency** (AWS Lambda) for zero cold starts
4. **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:**

```typescript theme={null}
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:

```typescript theme={null}
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:

```typescript theme={null}
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

```bash theme={null}
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](/integrations/browserbase) for details.

### Browser Use

```bash theme={null}
export BROWSER_USE_API_KEY="your-api-key"
export AGENT_BROWSER_PROVIDER=browseruse

agent-browser open https://example.com
```

See [Browser Use integration](/integrations/browser-use) for details.

### Kernel

```bash theme={null}
export KERNEL_API_KEY="your-api-key"
export AGENT_BROWSER_PROVIDER=kernel

agent-browser open https://example.com
```

See [Kernel integration](/integrations/kernel) 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:

1. **Memory is sufficient** (at least 1024 MB, recommended 2048+ MB)
2. **Timeout is adequate** (at least 30 seconds)
3. **executablePath is correct:**
   ```typescript theme={null}
   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:

```bash theme={null}
# 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](/guides/troubleshooting) for more common issues.
