Skip to content

Add Puppeteer support for Worker JavaScript and the worker shell - #148

Open
scuffi wants to merge 1 commit into
mainfrom
computer/puppeteer-plugin
Open

scuffi wants to merge 1 commit into
mainfrom
computer/puppeteer-plugin

Conversation

@scuffi

@scuffi scuffi commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

This adds a public Puppeteer plugin for Computer's Worker JavaScript backend. The plugin bundles Cloudflare's Worker-compatible Puppeteer client, connects it to a Browser Run binding, and keeps Browser and Page objects inside each isolated execution.

It exposes bound launch() and withBrowser() helpers, keeps plugin bindings separate from caller environment values, and closes connection-bound browser sessions when work completes or an execution is disposed.

The worker shell reaches the same capability through an opt-in browser command, so a browser task is available from a command line as well as from a module.

Usage

Register the plugin on the backend, then import Puppeteer from code executed by Computer:

import { Workspace } from "@cloudflare/computer";
import { WorkerJavaScriptBackend } from "@cloudflare/computer/backends/worker-javascript";
import { puppeteer } from "@cloudflare/computer/plugins/puppeteer";

const workspace = new Workspace({
  storage: ctx.storage,
  backends: [new WorkerJavaScriptBackend({
    loader: env.LOADER,
    plugins: [puppeteer({ browser: env.BROWSER })],
  })],
});

using execution = await workspace.runtime.exec(`
  import { withBrowser } from "@cloudflare/puppeteer";

  export default ({ url }) => withBrowser(async (browser) => {
    const page = await browser.newPage();
    await page.goto(url);
    return { title: await page.title() };
  });
`, { input: { url: "https://example.com" } });

const result = await execution.result();

Shell usage

Add the command group to a worker shell backend in the same Workspace:

import { WorkerShellBackend } from "@cloudflare/computer/backends/worker-shell";
import browser from "@cloudflare/computer/shell/browser";

new WorkerShellBackend({
  loader: env.LOADER,
  workspace: { binding: "Agent", id: ctx.id.toString() },
  ctx,
  commands: [browser],
});

A task module is an ordinary module whose default export receives a live browser alongside the caller's input:

// /workspace/tasks/title.js
export default async ({ url, browser }) => {
  const page = await browser.newPage();
  await page.goto(url);
  return { title: await page.title() };
};
browser puppeteer --url https://example.com/ tasks/title.js
browser puppeteer --url https://example.com/ --stdin < tasks/title.js

The shell does not drive the browser itself. The command resolves the task from the Workspace, wraps it in the same withBrowser() entry shown above, and dispatches that entry into the JavaScript backend carrying the plugin, so Puppeteer stays in the isolate. It prints the task's return value as JSON and exits with the task's exit code. --timeout sets the execution budget, --input merges a JSON object into the task input, and a --url confines the session to that host, its subdomains, and common content delivery networks.

Because the task runs in the JavaScript backend, it can write to the Workspace through node:fs/promises, so a stored task can be named, rerun, and edited, and its output outlives the execution that produced it.

Browser rendering example

The new self-hosted example stores one browser task in the Workspace and runs it both ways, as a JavaScript module and as a shell command. Either path writes report.md, page.json, and screenshot.png to one Workspace directory from a single isolated execution.

The package and architecture documentation cover Browser Run setup, lifecycle, limits, plugin authoring, and the authority granted to browser-enabled backends.

@changeset-bot

changeset-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown

馃 Changeset detected

Latest commit: fac6026

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@cloudflare/computer Minor
@cloudflare/dofs Minor
@cloudflare/computer-rpc Minor
@cloudflare/computerd Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your interest in Cloudflare Computer.

This repository does not accept unsolicited pull requests. Please use one of the accepted contribution paths instead:

If a maintainer asked you to open this pull request, they can add the allow-pr label and reopen it.

@github-actions github-actions Bot closed this Sep 17, 2026
@scuffi scuffi added the allow-pr Allow a PR to remain open. label Sep 17, 2026
@scuffi scuffi reopened this Sep 17, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from d14c26a to 21a34da Compare September 17, 2026 15:33

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 0 new potential issues.

Devin Review

@pkg-pr-new

pkg-pr-new Bot commented Sep 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@cloudflare/computer@148

commit: fac6026

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 21a34da to 6aaabd9 Compare September 17, 2026 15:42
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 6aaabd9 to 7951b3d Compare September 17, 2026 17:04
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 7951b3d to 27c19b1 Compare September 17, 2026 18:02
@aron-cf

aron-cf commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

This is awesome, I'd love to keep worker shell backend in similar parity with the js one. What do you think to adding a browser CLI tool that takes a pupetteer flag or something.

browser puppeteer --url http://example.com run.js
browser puppeteer --url <url> --stdin <run.js

Where run.js is has a global browser instance:

export default async ({ url, browser }) => {
    const page = await browser.newPage();
    await page.goto(url);
    return { title: await page.title() };
});

@aron-cf aron-cf closed this Sep 18, 2026
@aron-cf aron-cf reopened this Sep 18, 2026
@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 27c19b1 to 44bb703 Compare September 21, 2026 10:11
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 44bb703 to 4f0e944 Compare September 21, 2026 10:33
@scuffi scuffi changed the title Add Puppeteer support for Worker JavaScript Add browser automation for Worker JavaScript and the worker shell Sep 21, 2026
@scuffi scuffi changed the title Add browser automation for Worker JavaScript and the worker shell Add Puppeteer support for Worker JavaScript and the worker shell Sep 21, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from 4f0e944 to 00f8db1 Compare September 21, 2026 10:47
devin-ai-integration[bot]

This comment was marked as resolved.

@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch 2 times, most recently from 5dc797e to deb4e4e Compare September 21, 2026 11:20

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 new potential issues.

Devin Review

Comment thread packages/computer/src/backends/worker-javascript/module-graph.ts Outdated
Comment thread packages/computer/src/backends/worker-shell/browser/command.ts
Comment thread .gitignore
# packages/computer/src/backends/worker-shell/script/build-bundle.mjs on
# prepare / pretest / pretypecheck.
packages/computer/src/backends/worker-shell/generated/
packages/computer/src/plugins/puppeteer/generated.ts

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃攳 Source imports require generation first

The plugin imports ignored generated.ts. npm hooks create it, but source-based tooling that skips scripts cannot load this entrypoint.

Devin Review


Was this helpful? React with 馃憤 or 馃憥 to provide feedback.

Comment thread packages/computer/src/backends/worker-shell/worker-shell.ts Outdated
@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch 2 times, most recently from 35bb603 to fb1f4e7 Compare September 21, 2026 11:43
@scuffi
scuffi force-pushed the computer/puppeteer-plugin branch from fb1f4e7 to fac6026 Compare September 21, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

allow-pr Allow a PR to remain open.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants