実行時に別の Worker(Dynamic Workers)を起動し、安全なサンドボックス環境でオンデマンドにコードを実行する Worker を作れます。コードを渡し、Dynamic Worker が使えるバインディングを選び、ネットワーク到達の可否を制御します。
Dynamic Workers には、2 つの読み込みモードがあります。
load(code)は、1 回限りの実行向けに新しい Dynamic Worker を作成します。get(id, callback)は、ID ごとに Dynamic Worker をキャッシュし、リクエストをまたいでウォームな状態を保てます。
load() は 1 回限りのコード実行に向いています。たとえば Code Mode を使う場合です。get(id, callback) は、同じコードが後続リクエストを受ける場合に向いています。たとえばアプリケーションを構築する場合です。
この "hello world" スターター ↗ を使うと、Dynamic Workers を読み込んで実行できる Worker をデプロイできます。
Dynamic Workers Playground ↗ をデプロイすることもできます。コードの作成またはインポート、@cloudflare/worker-bundler による実行時バンドル、Dynamic Worker での実行、リアルタイムの応答と実行ログの確認ができます。
Worker が Dynamic Workers を作成できるようにするには、Worker Loader バインディングが必要です。ほとんどの Workers バインディングと異なり、このバインディングは特定の外部リソースを指しません。Worker Loader API へのアクセスを提供するだけです。
Worker の wrangler.jsonc で、次のように設定します。
{
"worker_loaders": [
{
"binding": "LOADER",
},
],
}[[worker_loaders]]
binding = "LOADER"これで Worker は env.LOADER から Worker Loader API を使えます。
env.LOADER.load() を使い、Dynamic Worker を作成して実行します。
export default {
async fetch(request, env) {
// Load a worker.
const worker = env.LOADER.load({
compatibilityDate: "2026-09-20",
mainModule: "src/index.js",
modules: {
"src/index.js": `
export default {
fetch(request) {
return new Response("Hello from a dynamic Worker");
},
};
`,
},
// Block all outbound network access from the Dynamic Worker.
globalOutbound: null,
});
// Get the Dynamic Worker's `export default` entrypoint.
// (A Worker can also export separate, named entrypoints.)
let entrypoint = worker.getEntrypoint();
// Forward the HTTP request to it.
return entrypoint.fetch(request);
},
};export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Load a worker.
const worker = env.LOADER.load({
compatibilityDate: "$today",
mainModule: "src/index.js",
modules: {
"src/index.js": `
export default {
fetch(request) {
return new Response("Hello from a dynamic Worker");
},
};
`,
},
// Block all outbound network access from the Dynamic Worker.
globalOutbound: null,
});
// Get the Dynamic Worker's `export default` entrypoint.
// (A Worker can also export separate, named entrypoints.)
let entrypoint = worker.getEntrypoint();
// Forward the HTTP request to it.
return entrypoint.fetch(request);
},
};この例では、env.LOADER.load() が modules で定義したコードから Dynamic Worker を作成し、それを表すスタブを返します。
worker.getEntrypoint().fetch(request) は、受信リクエストを Dynamic Worker の fetch() ハンドラーへ送ります。ハンドラーが処理し、応答を返します。
まったく同じ Worker を複数回読み込む場合は、load() ではなく get(id, callback) を使います。id は、読み込む特定のコードを識別する一意の文字列にしてください。ランタイムが同じ id を再度見ると、まだエビクションされていなければ、新しい Worker を作らず既存の Worker を再利用できます。
渡したコールバックは、Worker がまだ読み込まれていない場合にだけ呼ばれます。Worker がすでに動いているときは、ストレージからコードを読み込む処理を省略できます。
const worker = env.LOADER.get("hello-v1", async () => {
// Callback only runs if there is not already a warm
// instance available.
// Load code from storage.
let code = await env.MY_CODE_STORAGE.get("hello-v1");
// Return the same format as `env.LOADER.load()` accepts.
return {
compatibilityDate: "2026-09-20",
mainModule: "index.js",
modules: { "index.js": code },
globalOutbound: null,
};
});const worker = env.LOADER.get("hello-v1", async () => {
// Callback only runs if there is not already a warm
// instance available.
// Load code from storage.
let code = await env.MY_CODE_STORAGE.get("hello-v1");
// Return the same format as `env.LOADER.load()` accepts.
return {
compatibilityDate: "$today",
mainModule: "index.js",
modules: { "index.js": code, },
globalOutbound: null,
};
});Dynamic Workers は JavaScript(ES modules と CommonJS)、Python、WebAssembly(Wasm)モジュールに対応しています。JavaScript と Python のコードは、modules オブジェクトに文字列として渡します。コンパイル済み Wasm バイナリは { wasm: ArrayBuffer } モジュールオブジェクトとして渡します。
ビルドステップはないため、TypeScript のような言語は、load() または get() に渡す前に JavaScript へコンパイルする必要があります。
対応するモジュールタイプの一覧は、API リファレンス を参照してください。
Dynamic Worker で Python コードを実行するには、python_workers 互換性フラグが必要です。このフラグがないと、Dynamic Worker は Python ランタイムの読み込みに失敗します。
const worker = env.LOADER.load({
compatibilityDate: "2026-09-20",
compatibilityFlags: ["python_workers"],
mainModule: "worker.py",
modules: {
"worker.py": `
from workers import Response, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
return Response("Hello from Python!")
`,
},
});const worker = env.LOADER.load({
compatibilityDate: "$today",
compatibilityFlags: ["python_workers"],
mainModule: "worker.py",
modules: {
"worker.py": `
from workers import Response, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
return Response("Hello from Python!")
`,
},
});Dynamic Worker に TypeScript のコンパイルや npm 依存関係が必要な場合は、Worker Loader に渡す前にトランスパイルとバンドルが必要です。
@cloudflare/worker-bundler ↗ は、これを行うライブラリです。ソースファイルを、load() と get() が受け付ける形式にバンドルします。
import { createWorker } from "@cloudflare/worker-bundler";
const worker = env.LOADER.get("my-worker", async () => {
const { mainModule, modules } = await createWorker({
files: {
"src/index.ts": `
import { Hono } from 'hono';
const app = new Hono();
app.get('/', (c) => c.text('Hello from Hono!'));
export default app;
`,
"package.json": JSON.stringify({
dependencies: { hono: "^4.0.0" },
}),
},
});
return { mainModule, modules, compatibilityDate: "2026-09-20" };
});import { createWorker } from "@cloudflare/worker-bundler";
const worker = env.LOADER.get("my-worker", async () => {
const { mainModule, modules } = await createWorker({
files: {
"src/index.ts": `
import { Hono } from 'hono';
const app = new Hono();
app.get('/', (c) => c.text('Hello from Hono!'));
export default app;
`,
"package.json": JSON.stringify({
dependencies: { hono: "^4.0.0" },
}),
},
});
return { mainModule, modules, compatibilityDate: "$today" };
});createWorker() は TypeScript のコンパイル、npm からの依存関係解決、バンドルを行います。load() または get() にそのまま渡せる mainModule と modules を返します。