Compute & Isolation
Dynamic Worker Runner
Execute untrusted JavaScript via Dynamic Workers with no network access
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