Introduction
@ltv/cwb (Cloudflare Workers Bootstrap) is a library for building OpenAPI-documented REST APIs on Cloudflare Workers with Hono and chanfana.
You write chanfana route classes and your data access. @ltv/cwb supplies the parts every production API rebuilds from scratch: app wiring with a safe middleware order, versioned modules, one response envelope, matching OpenAPI response schemas, typed errors that are masked in production, structured logging, typed environment readers, KV caching, and optional Drizzle ORM datasources for D1 with multi-tenant query scoping.
It is a library, not a template: you install it from npm and keep your own Worker project.
These pages describe @ltv/cwb 0.2.0. Coming from 0.1.x? Start with the migration guide.
Why use it
- One way to build an API.
createAppregisters built-in middleware, your middleware, module routes and the OpenAPI docs in an order that makes auth middleware guard every route. - Predictable responses. Success and error bodies share one envelope,
c.respond*helpers produce it, and thejson*schema helpers document it in OpenAPI. - Safe by default. Anything other than an explicit development
NODE_ENVcounts as production: 5xx messages are masked, raw database errors never reach clients, and sensitive headers and query parameters are redacted from logs. - Workers-aware. pino is configured for the browser build that Workers bundles, background work goes through
waitUntil, and KV invalidation stays within the per-invocation operation limit. - Tenant isolation you can't forget.
DrizzleD1TenantDatasourcescopes reads and writes to the current tenant and returns narrow query objects that can't drop the tenant filter.
Features
- App builder:
createAppwith request ids, CORS,Server-Timing, request logging, a/healthroute, a JSON 404 and app-wide middleware. See App builder. - Modules and versioning:
defineModule({version, routes, middleware})with validated"METHOD /path"route keys. See Modules and versioning. - Response envelope:
c.respond,c.respondPaginated,c.respondErrorand shortcuts, plus theApiResponseunion type. See Responses. - OpenAPI schemas:
jsonSuccess,jsonPaginated,jsonCrudResponsesand friends. See OpenAPI schema helpers. - Errors:
ApiErrorfactories,createErrorHandlerwith masking, redaction, reporters, throttling and per-isolate metrics. See Error handling. - Logging: a pino root logger, request-scoped loggers bound to
requestId, and safe serializers. See Logging. - Environment:
env.default.string/int/bool/json/...readers and theNODE_ENV,LOG_LEVELandSERVICE_NAMEconstants. See Environment variables. - KV caching:
KVCache.memoizewith stable keys, TTL clamping and budgeted invalidation. See KV caching. - Datasources:
AbstractDatasourceandDrizzleD1Datasourcefrom@ltv/cwb/datasources. See Drizzle D1 datasources. - Multi-tenancy:
DrizzleD1TenantDatasourcewithscoped*helpers. See Multi-tenancy.
Requirements
| Component | Requirement |
|---|---|
| Runtime | Cloudflare Workers only. The package imports cloudflare:workers when it loads. Plain Node or Bun can import it only if that module is mocked (for tests). |
compatibility_date | 2026-01-14 or later (the tested date) |
nodejs_compat flag | Recommended (the verified configuration) |
hono | ^4.13.0 (peer, must resolve to a single copy) |
chanfana | ^3.4.0 (peer) |
zod | ^4.4.3 (peer) |
drizzle-orm | >=0.45.0 <0.46.0 (optional peer, only for @ltv/cwb/datasources) |
| TypeScript | 5.9, 6.0 or 7.0 in your project. Not a peer dependency. |
The package has two entry points:
| Import | Contents |
|---|---|
@ltv/cwb | App builder, modules, response helpers, OpenAPI schemas, errors, logging, env, KV cache, utilities |
@ltv/cwb/datasources | AbstractDatasource, DrizzleD1Datasource, DrizzleD1TenantDatasource and tenant helpers |
Where to go next
- Install the package and set up TypeScript.
- Build a first endpoint in the quick start.
- Read the basic Worker example for D1, KV and tenants working together.
- Look up any export in the API reference.