Bundle source files for Cloudflare's Worker Loader binding (closed beta). Perfect for AI coding agents that need to dynamically generate and deploy javascript code with real npm dependencies.
npm install workers-builderJust provide your source code and dependencies — no config files needed:
import { createWorker } from 'workers-builder';
const worker = env.LOADER.get('my-worker', async () => {
const { mainModule, modules } = await createWorker({
files: {
'src/index.ts': `
import { Hono } from 'hono';
import { cors } from 'hono/cors';
const app = new Hono();
app.use('*', cors());
app.get('/', (c) => c.text('Hello from Hono!'));
app.get('/json', (c) => c.json({ message: 'It works!' }));
export default app;
`,
'package.json': JSON.stringify({
dependencies: {
hono: '^4.0.0'
}
}),
},
});
return { mainModule, modules, compatibilityDate: '2026-01-01' };
});
await worker.getEntrypoint().fetch(request);The library automatically:
- Detects your entry point (
src/index.tsby default) - Fetches and installs npm dependencies from the registry
- Bundles everything with esbuild
- Returns modules ready for the Worker Loader binding
| Option | Type | Default | Description |
|---|---|---|---|
files |
Record<string, string> |
required | Source files (path → content) |
entryPoint |
string |
auto | Override entry point detection |
bundle |
boolean |
true |
Bundle into single file |
externals |
string[] |
[] |
Additional modules to exclude (cloudflare:* always excluded) |
minify |
boolean |
false |
Minify output |
sourcemap |
boolean |
false |
Generate inline source maps |
registry |
string |
'https://registry.npmjs.org' |
npm registry URL |
{
mainModule: string; // Entry point path
modules: Record<string, string>; // All output modules
wranglerConfig?: { // Parsed from wrangler.toml/json/jsonc
main?: string;
compatibilityDate?: string;
compatibilityFlags?: string[];
};
warnings?: string[]; // Any warnings during bundling
}Priority order:
entryPointoptionmainfield in wrangler configexports,module, ormainfield in package.json- Default paths:
src/index.ts,src/index.js,index.ts,index.js
const worker = env.LOADER.get('my-worker', async () => {
const { mainModule, modules } = await createWorker({
files: {
'src/index.ts': `
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const app = new Hono();
const schema = z.object({ name: z.string() });
app.post('/greet', zValidator('json', schema), (c) => {
const { name } = c.req.valid('json');
return c.json({ message: \`Hello, \${name}!\` });
});
export default app;
`,
'package.json': JSON.stringify({
dependencies: {
hono: '^4.0.0',
'@hono/zod-validator': '^0.4.0',
zod: '^3.23.0'
}
}),
},
});
return { mainModule, modules, compatibilityDate: '2026-01-01' };
});For projects that need specific compatibility settings or are migrating from existing Workers:
const worker = env.LOADER.get('my-worker', async () => {
const { mainModule, modules, wranglerConfig } = await createWorker({
files: {
'src/index.ts': `
export default {
fetch: () => new Response('Hello!')
}
`,
'wrangler.toml': `
main = "src/index.ts"
compatibility_date = "2026-01-01"
compatibility_flags = ["nodejs_compat"]
`,
},
});
return {
mainModule,
modules,
compatibilityDate: wranglerConfig?.compatibilityDate ?? '2026-01-01',
compatibilityFlags: wranglerConfig?.compatibilityFlags,
};
});Skip bundling to preserve module structure:
const worker = env.LOADER.get('my-worker', async () => {
const { mainModule, modules } = await createWorker({
files: { /* ... */ },
bundle: false,
});
return { mainModule, modules, compatibilityDate: '2026-01-01' };
});# wrangler.toml (host worker)
[[worker_loaders]]
binding = "LOADER"interface Env {
LOADER: WorkerLoader;
}- Lockfile support: Read
package-lock.json/pnpm-lock.yamlfor deterministic installs
MIT