# How to run Playwright in a cloud sandbox Install Playwright and Chromium in a Linux microVM, run your script there, and copy the screenshots or results back. **On Runtime it takes one sandbox and three commands.** Every sandbox is a Firecracker microVM running Ubuntu 24.04 with Node.js 24 and `sudo`, so Playwright's own installer works unchanged. Build it into an image once and every later sandbox starts with Chromium ready. Playwright 1.63.0 was the current release on 24 September 2026. ## Take a screenshot ```ts check import { writeFile } from "node:fs/promises"; import { Sandbox } from "withruntime"; const script = ` import { chromium } from "playwright"; const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto(process.argv[2]); await page.screenshot({ path: "shot.png", fullPage: true }); console.log(await page.title()); await browser.close(); `; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 900 }); const slow = { check: true, timeoutMs: 600_000 } as const; await sbx.exec("npm install --no-fund --no-audit playwright@1.63.0", slow); await sbx.exec("sudo npx playwright install-deps chromium", slow); await sbx.exec("npx playwright install chromium", slow); await sbx.files.write("/workspace/shot.mjs", script); const run = await sbx.exec(["node", "shot.mjs", "https://example.com"], { check: true }); console.log(run.stdout); // the page's title await writeFile("shot.png", await sbx.files.read("/workspace/shot.png")); ``` - **Disk:** ask for 8 GiB. The default 4 GiB sandbox has about 2.5 GiB free, and Chromium with its system libraries takes a large share of that. - **Timeouts:** installs take longer than the 60-second default for a command, so give them `timeoutMs`. - **The free trial** reaches ports 80 and 443, which is all Playwright's installer and most sites need. Paid sandboxes reach any port. ## Install once, start ready Put Chromium in a [custom image](/docs/images) and every sandbox made from it skips the install. Building an image is free; a stored image is charged on its size, and the free trial stores your first three free. ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); await runtime.images.build({ name: "playwright", recipe: { env: { PLAYWRIGHT_BROWSERS_PATH: "/opt/ms-playwright" }, commands: [ "npm init -y && npm install --no-fund --no-audit playwright@1.63.0", "npx playwright install --with-deps chromium", ], }, }); await using sbx = await runtime.sandboxes.create({ image: "playwright" }); await sbx.exec("node -e \"require('playwright').chromium.launch().then(b => b.close())\"", { check: true, }); ``` Recipe commands run as root in `/workspace`. `PLAYWRIGHT_BROWSERS_PATH` puts the browser where the sandbox's own user finds it. ## Run your test suite For `@playwright/test`, upload the project and run it as you would locally: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ image: "playwright", timeoutSeconds: 1800 }); await sbx.files.upload("./e2e", "/workspace/e2e"); const run = await sbx.exec("cd e2e && npm ci && npx playwright test --reporter=line", { timeoutMs: 1_200_000, onStdout: (text) => process.stdout.write(text), }); await sbx.files.download("/workspace/e2e/playwright-report", "./playwright-report"); process.exitCode = run.exitCode ?? 1; ``` Output streams as the tests run. The report comes back as a folder in one call. ## Test an app running in the same sandbox Start your server in the background and point Playwright at `localhost`: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ image: "playwright" }); await sbx.files.upload("./app", "/workspace/app"); await sbx.spawn("cd app && npm ci && npm start"); await sbx.exec("npx wait-on http://localhost:3000", { check: true, timeoutMs: 180_000 }); await sbx.exec("cd app && npx playwright test", { check: true, timeoutMs: 600_000 }); ``` To watch the app yourself, share the port as a private HTTPS [preview](/docs/javascript#share-a-port). ## Let an agent drive the browser An agent that needs to click through a site can use the sandbox's [desktop](/docs/javascript#a-desktop), which takes clicks and keys and returns screenshots, or run the Playwright MCP server inside the sandbox ([MCP servers in a sandbox](/docs/javascript#mcp-servers-in-a-sandbox)). For a full agent loop of screenshots, clicks and typing, see [a browser automation agent](/use-cases/browser-automation-agent). ## Many browsers at once Each sandbox is its own machine, so parallel runs never share a browser profile, cookies or downloads. A paid account runs 100 sandboxes at once to start with. A 2 vCPU, 4 GiB sandbox costs $0.08 an hour with both CPUs busy and $0.03125 an hour while it waits on a page, because Runtime bills the CPU your code uses ([pricing](/docs/pricing)). For end-to-end tests of apps an agent builds, see [preview agent-built apps](/use-cases/preview-agent-built-apps); to keep untrusted pages away from your network, see [run untrusted LLM code](/use-cases/run-untrusted-llm-code). New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- node --version ``` Facts on this page were checked on 24 September 2026.