A demonstration of Cloudflare's new Worker Loaders feature, showcasing how to dynamically create and execute workers at runtime. This project explores the capabilities of creating workers on-demand with custom modules, environment bindings, and service integrations.
- Dynamic Worker Creation: Create workers programmatically using the
LOADER
binding - Custom Module System: Define and import custom JavaScript modules within dynamic workers
- Environment Bindings: Pass environment variables, JSON objects, and service bindings to dynamic workers
- Service Integration: Expose functions and services that can be called from within dynamic workers
- Network Control: Implement custom fetch behavior with global outbound controls
- Node.js Compatibility: Full Node.js built-in module support within dynamic workers
This project consists of:
- Main Worker (
src/index.ts
): The primary worker that creates and manages dynamic workers - Worker Loader: Uses Cloudflare's
LOADER
binding to instantiate workers on-demand - Service Exports: Exposes utility functions that can be called from dynamic workers
- Global Outbound: Custom fetch implementation for controlling network requests
npm install
npm start
The main worker creates dynamic workers using the LOADER
binding:
const worker = env.LOADER.get(`${url.pathname}-${Math.random()}`, () => {
return {
compatibilityDate: "2025-06-01",
compatibilityFlags: ["nodejs_compat"],
mainModule: "foo.js",
modules: {
"foo.js": `/* Your dynamic worker code */`,
"bar.js": `/* Additional modules */`,
},
env: {
TEXT: "Environment variable",
JSON: {
/* JSON binding */
},
exposed: ctx.exports.ExposeSomeFunctions(),
},
};
});
Dynamic workers can define and import custom modules:
// Inside dynamic worker
import bar from "./bar.js";
import util from "node:util";
export default {
async fetch(req) {
// Worker logic here
return new Response("Hello from dynamic worker!");
},
};
The main worker exposes services that can be called from dynamic workers:
export class ExposeSomeFunctions extends WorkerEntrypoint {
async addNumbers(a: number, b: number) {
return a + b;
}
async spongeBobText(text: string) {
// SpongeBob case transformation
return text
.split("")
.map((char) =>
Math.random() > 0.5 ? char.toUpperCase() : char.toLowerCase()
)
.join("");
}
}
Global outbound controls allow customizing fetch behavior:
export const globalOutbound = {
fetch: async (input, init) => {
const url = new URL(input);
if (url.hostname === "example.com" && url.pathname === "/sub-path") {
return new Response("Not allowed", { status: 403 });
}
return fetch(input, init);
},
};
The project uses several Cloudflare Workers features:
- Worker Loaders: For dynamic worker creation
- Durable Objects: For stateful operations
- KV Storage: For key-value data
- Services: For inter-worker communication
- Migrations: For database schema management
See wrangler.jsonc
for complete configuration.
The dynamic workers demonstrate:
- Node.js Built-ins: Using
util.isDeepStrictEqual()
and other Node.js modules - Custom Modules: Importing and using custom JavaScript modules
- Environment Access: Reading environment variables and JSON bindings
- Service Calls: Calling exposed functions from the main worker
- Network Requests: Making controlled fetch requests
- Response Generation: Creating custom HTTP responses
This technology enables:
- Plugin Systems: Dynamic code execution for extensible applications
- User Scripts: Safe execution of user-provided code
- Microservices: On-demand service creation
- A/B Testing: Dynamic feature toggling
- Code Sandboxing: Isolated execution environments
- Dynamic workers run in isolated environments
- Network access can be controlled via global outbound
- Environment bindings provide controlled access to resources
- Service calls are authenticated and authorized
ISC License - see package.json for details.