@moku-labs/worker
Cloudflare Workers backend. D1, KV, R2, Queues, DO — each one a plugin.
Overview
@moku-labs/worker is the Cloudflare Workers backend for Moku. Every Cloudflare primitive is a
plugin that resolves its binding per request from the Worker env. A server plugin owns HTTP
routing and dispatch. The build-time deploy and cli plugins ship the Worker but stay out of the
runtime bundle.
- Every primitive is a plugin. KV, D1, R2, Queues and Durable Objects. Add only what you use; the rest tree-shakes away.
envis a call argument, never state. One isolate serves many requests at once, so a binding lives on the call stack and cannot leak between them.- Not an ORM, not a router framework. Thin typed wrappers over the real Cloudflare APIs.
| Plugin | What it does |
|---|---|
bindings | Resolves bindings from the per-request env. A default. |
server | HTTP routing and request dispatch. A default. |
kv, d1, storage, queues, durableObjects | KV, D1, R2, Queues and Durable Objects. |
deploy, cli | Provision, generate the wrangler config, deploy. Node only. |
Install
bun add @moku-labs/worker bun add -d @cloudflare/workers-types
Quick start
Declare the routes as data. bindings and server are defaults: you never list them.
import { createApp, endpoint } from "@moku-labs/worker";
export const app = createApp({
config: { name: "my-api", compatibilityDate: "2026-06-17" },
pluginConfigs: {
server: {
endpoints: [
endpoint("/health").get(() => new Response("ok")),
endpoint("/api/data/{lang:?}").get(({ params }) =>
Response.json({ lang: params.lang ?? "en" })
),
endpoint("/users/{userId}").get(({ params }) => new Response(`user=${params.userId}`))
]
}
}
});- {lang:?} is optional, typed string | undefined.
The Worker entry is yours. It hands every request to app.server:
import { app } from "./app";
export default {
fetch: (request: Request, env: Record<string, unknown>, ctx: ExecutionContext) =>
app.server.handle(request, env, ctx)
} satisfies ExportedHandler;A request to /api/data/fr returns { "lang": "fr" }. An unmatched path returns 404.
Start with Claude
Describe what you want. The conductor picks the packages.
Build a blog with tags and an RSS feed on @moku-labs/web
Add a D1-backed comments API with @moku-labs/worker
Make a couch quiz game: TV shows questions, phones answer
Ship this app to macOS and iOS