Kernel provides first-class support for browser automation frameworks, supporting CDP (Chrome DevTools Protocol) connections like Playwright and Puppeteer out of the box. When using Kernel’s app platform, we co-locate your code with the browser environment in the cloud. This solves common issues with remote browsers:
  • Reduced latency: Your code runs directly alongside the browser, reducing round-trip latency
  • Improved reliability: No unexpected disconnects between your code and browser
  • Higher throughput: Eliminates bandwidth bottlenecks during data-intensive operations like screenshots
  • Simplified debugging: Access to browser logs and execution context in the same environment

Creating a browser automation app

To create a browser automation app with Kernel, simply define an app and action that creates a Kernel browser.

1. Create an app and define a browser action

Start by creating your app and defining an action for your browser automation:
import { Kernel } from '@onkernel/sdk';

const kernel = new Kernel();
const app = kernel.app('browser-automation');

const playwrightScript = async (runtimeContext, payload) => {
// ...
};

app.action("my-action-name", playwrightScript);

2. Connect to a browser in your action

Within your action, use Kernel’s browsers.create() method to generate a CDP websocket URL for your browser automation framework. browsers.create() requires the runtime’s invocation_id when you deploy and launch your app on Kernel. This is provided to you in the runtimeContext object generated during the invocation’s lifecycle:
const playwrightScript = async (runtimeContext, payload) => {
	const kernelBrowser = await kernel.browsers.create({ invocation_id: runtimeContext.invocation_id });
	const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
	// ...
};

3. Complete example

Kernel browsers launch with a default context and page. Make sure to access the existing context and page (contexts()[0] and pages()[0]), rather than trying to create a new one.
import { Kernel } from '@onkernel/sdk';
import { chromium } from 'playwright';

const kernel = new Kernel();
const app = kernel.app('browser-automation');

const playwrightScript = async (runtimeContext, payload) => {
  const kernelBrowser = await kernel.browsers.create({ invocation_id: runtimeContext.invocation_id });
  const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);

  try {
    const context = await browser.contexts()[0] || (await browser.newContext());
    const page = await context.pages()[0] || (await context.newPage());
    await page.goto("https://www.google.com");
    const title = await page.title();
    return title;
  } catch (error) {
    console.error(error);
    throw error;
  } finally {
    await browser.close();
  }
};

app.action("my-action-name", playwrightScript);
Make sure to call browser.close() at the end of your action to ensure the browser connection is properly closed.

Web agent frameworks: environment variables

Web agent frameworks sometimes require environment variables (e.g. LLM API keys). Set them when deploying your app.