Skip to content
Moku LabsDocs
@moku-labs/worker pages

@moku-labs/worker

Cloudflare Workers backend. D1, KV, R2, Queues, DO — each one a plugin.

worker.mdllms.txt

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.
  • env is 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.
PluginWhat it does
bindingsResolves bindings from the per-request env. A default.
serverHTTP routing and request dispatch. A default.
kv, d1, storage, queues, durableObjectsKV, D1, R2, Queues and Durable Objects.
deploy, cliProvision, 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.

app.ts
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}`))
      ]
    }
  }
});
  1. {lang:?} is optional, typed string | undefined.

The Worker entry is yours. It hands every request to app.server:

worker.ts
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