Compute & Isolation
Dynamic Worker Runner
Execute untrusted JavaScript via Dynamic Workers with no network access - isolate and run user code safely
Run untrusted JavaScript as an ES module Worker using the Worker Loader API. Loaded workers run with globalOutbound: null so they cannot make network requests.
API Reference
POST /run
Execute a Worker module string and return its HTTP response status and body.
code string (required)
Full ES module that exports default { fetch }. Max length 10,000 characters.
Example Request
curl -X POST "https://your-worker.workers.dev/run" \
-H "Content-Type: application/json" \
-d '{"code":"export default { async fetch() { return Response.json({ hello: \"world\" }); } }"}'Success Response
{
"status": 200,
"body": { "hello": "world" }
}Error Codes
400- Missing, empty, or too-long code (INVALID_CODE)502- Loader or isolate failure (RUN_ERROR)
Use Cases
- Learn Dynamic Workers / Worker Loader patterns safely
- Sandbox plugin or customer code without outbound network
- Prototype multi-tenant execution before Workers for Platforms
- Teach isolate isolation and
globalOutboundrestrictions
Limitations
- Code must be a complete ES module with
default { fetch } - Max code length 10,000 characters
- No outbound network from the loaded worker
- Dynamic Workers / Worker Loader may require account entitlements
Use in your project
Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/dynamic-worker-runner.
DependenciesNoneBindingsNonePlatformWeb Crypto, Fetch API
import { COMPATIBILITY_DATE, MAIN_MODULE, MAX_CODE_LENGTH } from "../constants/defaults";import type { Env, WorkerCode } from "../types/env";import type { RunResult } from "../types/run";export function validateCode(input: string | undefined): string | null { if (typeof input !== "string") return null; const trimmed = input.trim(); if (!trimmed || trimmed.length > MAX_CODE_LENGTH) return null; return trimmed;}export function buildWorkerCode(code: string): WorkerCode { return { compatibilityDate: COMPATIBILITY_DATE, mainModule: MAIN_MODULE, modules: { [MAIN_MODULE]: code, }, globalOutbound: null, };}async function hashId(code: string): Promise<string> { const data = new TextEncoder().encode(code); const digest = await crypto.subtle.digest("SHA-256", data); return Array.from(new Uint8Array(digest)) .map((b) => b.toString(16).padStart(2, "0")) .join("") .slice(0, 32);}export async function runDynamicWorker(env: Env, code: string): Promise<RunResult> { if (!env.LOADER) { throw new Error("LOADER binding is not configured"); } const id = await hashId(code); const workerCode = buildWorkerCode(code); const stub = env.LOADER.get(id, () => workerCode); const entrypoint = stub.getEntrypoint(); const response = await entrypoint.fetch(new Request("https://dynamic-worker/")); const contentType = response.headers.get("content-type") ?? ""; let body: unknown; if (contentType.includes("application/json")) { body = await response.json(); } else { body = await response.text(); } return { status: response.status, body };}Deployment
Deploy
Ensure your account supports Worker Loaders. wrangler.json binds LOADER via worker_loaders.
Test your deployment
curl -X POST "https://your-worker.workers.dev/run" \
-H "Content-Type: application/json" \
-d '{"code":"export default { async fetch() { return Response.json({ ok: true }); } }"}'Local Development
cd apps/experiments/dynamic-worker-runner
npm install
npm run devcurl -X POST "http://localhost:8787/run" \
-H "Content-Type: application/json" \
-d '{"code":"export default { async fetch() { return Response.json({ hello: \"world\" }); } }"}'Configuration
wrangler.json declares:
- Worker Loader binding
LOADER
Cloudflare Features Used
- Workers - Edge compute runtime
- Dynamic Workers / Worker Loaders - Load and run module code at request time