Skip to content

Dynamic Workers Playground

Try the Dynamic Workers playground to write or import code from GitHub, bundle it at runtime, execute it in a Dynamic Worker, and view real-time logs.

Deploy to Workers

Dynamic Workers Playground UI

What this demo shows

  • Runtime bundling — Uses @cloudflare/worker-bundler to resolve npm dependencies and compile TypeScript inside a Worker
  • Dynamic execution — Loads bundled code into an isolated Dynamic Worker
  • Caching — Reuses previously bundled Workers when the source has not changed
  • Real-time output — Streams the response body, console logs, execution timing, and bundle metadata back to the client

Bundling code at runtime

The playground uses @cloudflare/worker-bundler to compile TypeScript, resolve npm dependencies, and produce modules the Worker Loader can execute.

Pass source files and a package.json to createWorker(), which resolves dependencies and returns bundled modules ready to load as a Dynamic Worker:

JavaScript
import { createWorker } from "@cloudflare/worker-bundler";
const { mainModule, modules, warnings } = await createWorker({
files: {
"src/index.ts": userCode,
"package.json": JSON.stringify({
dependencies: { hono: "^4.0.0" },
}),
},
bundle: true,
minify: false,
});

Caching Dynamic Workers

env.LOADER.load() creates a new Dynamic Worker on every call. To avoid re-bundling unchanged code, use env.LOADER.get(id, callback) instead. The runtime returns an existing Worker on a cache hit, or calls your callback to build one on a miss:

JavaScript
const worker = env.LOADER.get(workerId, async () => {
// This callback only runs on cache miss
const { mainModule, modules } = await createWorker({ files });
return {
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [contextExports.DynamicWorkerTail({ props: { workerId } })],
};
});
const response = await worker.getEntrypoint().fetch(request);

In the playground, you can see this in action — run the same Dynamic Worker twice and the second request shows a cached result with 0ms cold start, since the build and load phases are skipped entirely.

Observability with Tail Workers

When you run code in the playground, console output from the Dynamic Worker streams back to the browser in real time. Under the hood, this works through a Tail Worker pipeline:

  1. A Tail Worker (DynamicWorkerTail) captures console.log output from the Dynamic Worker.
  2. Logs are forwarded to a LogSession Durable Object.
  3. The Durable Object streams them to the client over WebSocket.

To wire this up, include the Tail Worker in the tails array when creating the Dynamic Worker:

JavaScript
const worker = env.LOADER.get(workerId, async () => ({
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [contextExports.DynamicWorkerTail({ props: { workerId } })],
}));

For more information on how to capture and stream logs from Dynamic Workers, refer to Observability with Dynamic Workers.

Running locally

Clone the repo and start the dev server:

Terminal window
npm install
npm run dev