How to Deploy Serverless Browser Automation with Browserbase Functions

Browserbase Functions let you package Playwright-driven browser automation as a serverless cloud function by using the @browserbasehq/sdk-functions CLI to scaffold, develop locally with pnpm bb dev, and deploy with pnpm bb publish to obtain a Function ID for invocation via REST API.

If you need to run browser automation at scale without managing infrastructure, Browserbase Functions offer a managed solution within the browserbase/skills ecosystem. This guide walks through the complete workflow to deploy serverless browser automation with Browserbase Functions, from project initialization to production invocation.

What Are Browserbase Functions?

Browserbase Functions are serverless cloud functions specifically designed for browser automation workloads. According to skills/functions/SKILL.md, these functions wrap Playwright scripts inside a containerized environment hosted by Browserbase, allowing you to execute scraping, testing, or interaction tasks on demand without provisioning servers.

The architecture centers on three core components:

  • @browserbasehq/sdk-functions: The CLI and runtime library that packages your code.
  • defineFn: The registration function that exposes your automation logic.
  • context.session.connectUrl: A secure Chrome DevTools Protocol (CDP) endpoint providing access to a remote Chromium instance.

Prerequisites and Project Initialization

Before writing code, scaffold a new function project using the Browserbase SDK.

Installing the SDK

Initialize a new project using your preferred package manager. The CLI generates a minimal Node.js/TypeScript structure:

pnpm dlx @browserbasehq/sdk-functions init my-function
cd my-function

This creates package.json, a template index.ts entry file, and a .env placeholder for credentials.

Project Structure

The generated layout follows serverless function conventions:

  • index.ts: Your function implementation where Playwright automation lives.
  • .env: Stores BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID (never commit this file).
  • package.json: Declares the @browserbasehq/sdk-functions dependency.

Configure your credentials immediately after scaffolding:

echo "BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY" >> .env
echo "BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID" >> .env

Implementing Your Function

Implementation occurs inside index.ts, where you register an async handler that receives a managed browser session.

The defineFn Handler

Use defineFn from @browserbasehq/sdk-functions to register your function name and handler:

import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

defineFn("scrape-title", async ({ session, params }) => {
  // Handler implementation
});

The handler receives a context object containing:

  • session.connectUrl: The CDP endpoint for the remote browser.
  • params: Custom arguments passed during invocation.

Connecting to the Browser Session

Inside the handler, connect to the remote Chromium instance using chromium.connectOverCDP. The function must return a JSON-serializable value:

defineFn("scrape-title", async ({ session, params }) => {
  const browser = await chromium.connectOverCDP(session.connectUrl);
  const page = browser.contexts()[0]!.pages()[0]!;

  await page.goto(params.url ?? "https://example.com");
  const title = await page.title();

  return { success: true, title };
});

The SDK automatically serializes the return value and stores it as the invocation payload, as documented in skills/functions/SKILL.md.

Local Development and Testing

Test your function locally before deploying to production. Run the development server:

pnpm bb dev index.ts

This exposes a temporary HTTP endpoint at http://127.0.0.1:14113. Test your function using curl:

curl -X POST http://127.0.0.1:14113/v1/functions/scrape-title/invoke \
  -H "Content-Type: application/json" \
  -d '{"params": {"url": "https://news.ycombinator.com"}}'

Local development validates your Playwright logic without consuming remote Browserbase resources.

Deploying to Browserbase

When ready for production, publish your function:

pnpm bb publish index.ts

This command builds a container image, uploads it to Browserbase, and returns a Function ID. This ID serves as the permanent reference for your deployed serverless function.

The deployment process compiles your TypeScript, bundles dependencies, and configures the runtime environment according to specifications in skills/functions/SKILL.md.

Invoking Deployed Functions

Once deployed, invoke your function from any environment using the Browserbase REST API. Replace <FUNCTION_ID> with the ID returned during publishing:

curl -X POST "https://api.browserbase.com/v1/functions/<FUNCTION_ID>/invoke" \
  -H "Content-Type: application/json" \
  -H "x-bb-api-key: $BROWSERBASE_API_KEY" \
  -d '{"params": {"url": "https://example.com"}}'

The API returns an invocation ID that you can poll to retrieve results. For detailed invocation patterns and error handling, refer to skills/functions/REFERENCE.md.

Summary

  • Browserbase Functions package Playwright scripts as serverless cloud functions using the @browserbasehq/sdk-functions SDK.
  • Project setup requires running pnpm dlx @browserbasehq/sdk-functions init and configuring .env with your API credentials.
  • Implementation uses defineFn to register handlers that connect to remote browsers via chromium.connectOverCDP(session.connectUrl).
  • Development workflow supports local testing via pnpm bb dev index.ts, which exposes http://127.0.0.1:14113 for curl verification.
  • Deployment with pnpm bb publish index.ts generates a Function ID for REST API invocation at /v1/functions/<FUNCTION_ID>/invoke.

Frequently Asked Questions

What is the difference between Browserbase Functions and running Playwright locally?

Browserbase Functions execute your Playwright code inside Browserbase's managed infrastructure rather than your local machine. While local Playwright runs on your hardware, Browserbase Functions provide auto-scaling, persistent sessions, and remote invocation via REST API, eliminating the need to manage browser binaries or infrastructure.

How does the context.session.connectUrl parameter work?

The context.session.connectUrl is a secure Chrome DevTools Protocol (CDP) endpoint provided by Browserbase. When your function executes, Browserbase provisions a fresh Chromium instance and exposes it through this URL. Your handler uses chromium.connectOverCDP() to establish a connection, enabling standard Playwright operations on a remote browser as if it were local.

Can I deploy Browserbase Functions using environment variables other than .env?

Yes. While the CLI generates a .env template for local development, production deployments can inject BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID through your CI/CD pipeline's secret management system. The SDK reads these variables at runtime, regardless of whether they originate from a .env file or the hosting environment's secret store.

What happens if my function returns a non-JSON-serializable value?

The SDK requires all return values to be JSON-serializable. If your handler returns circular references, BigInt values, or other non-serializable objects, the function will fail at runtime. Always return plain objects, arrays, strings, numbers, or booleans to ensure the invocation payload can be stored and retrieved via the Browserbase API.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →