
Puppetless
v1.0.0
Fix browser automation that breaks in Base44's backend runtime — server-side puppeteering via raw Chrome DevTools Protocol, no puppeteer-core required.
automation
puppeteer
browserbase
backend
README
Puppetless
Server-side browser automation for Base44 apps that works reliably inside Base44's Deno backend function runtime — without puppeteer-core or playwright-core. No puppet, no strings, no problem.
The problem this solves
puppeteer-core (and playwright-core) need to serialize JavaScript function objects across the wire to run code inside the remote browser page (page.evaluate(fn)). Base44's Deno backend function runtime can't do that handoff reliably, which causes browser-automation functions built with puppeteer-core/playwright-core to fail intermittently or outright 500, especially when trying to intercept network responses or run in-page JS.
The fix
Puppetless talks the Chrome DevTools Protocol (CDP) directly over Deno's native WebSocket — no puppeteer-core dependency at all.
In-page JS runs via Runtime.evaluate with a plain string expression — never a serialized function.
Network response capture (e.g. intercepting an XHR/fetch API call a page makes) uses CDP's Network.responseReceived + Network.getResponseBody — no code injection into the page needed.
Both pieces have been tested live against a real Browserbase session, running inside an actual deployed Base44 backend function.
Requirements
A Browserbase account (their session infra is what actually runs the remote Chrome browser).
Two secrets in your Base44 app: BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID (found in Browserbase's dashboard under Settings).
What's included
functions/cdpBrowser.ts — a working, generic backend function you can call directly, or use as the reference implementation to fix/replace an existing broken puppeteer-core-based function.
Request format
{
"url": "https://example.com/some-form-page",
"evaluateExpression": "document.title",
"waitForNetworkUrlContains": "searchRaw",
"beforeCaptureExpression": "document.querySelector('#searchBtn').click()",
"navigateWaitMs": 1500,
"timeoutMs": 30000
}
url (required) — page to navigate to.
evaluateExpression (optional) — plain JS string to run in-page and return the result of.
waitForNetworkUrlContains (optional) — substring to match against response URLs; when set, waits for a matching response and returns its raw body.
beforeCaptureExpression (optional) — plain JS string run right before waiting for the network response (e.g. clicking a search/submit button that triggers the API call you want to capture).
Response format
{
"success": true,
"evaluatedResult": "...",
"capturedNetworkBody": "...",
"sessionId": "..."
}
Reply
Author
xBuildy
Category
Utilities
Downloads
1