Installation
Install the package
@ltv/cwb needs three peer dependencies: hono (^4.13), chanfana (^3.4) and zod (^4.4.3). Install them together with the library.
- bun
- npm
- pnpm
bun add @ltv/cwb hono chanfana zod
bun add -d wrangler
npm install @ltv/cwb hono chanfana zod
npm install --save-dev wrangler
pnpm add @ltv/cwb hono chanfana zod
pnpm add -D wrangler
Optional: Drizzle ORM for datasources
The @ltv/cwb/datasources entry point (Drizzle D1 datasources, multi-tenancy) needs drizzle-orm 0.45.x. It is an optional peer: skip it if you don't import that entry point.
- bun
- npm
- pnpm
bun add drizzle-orm@~0.45.0
npm install drizzle-orm@~0.45.0
pnpm add drizzle-orm@~0.45.0
@ltv/cwb is pre-1.0, so a minor release can contain breaking changes. Use a tilde range such as "@ltv/cwb": "~0.2.0" so upgrades across breaking releases are deliberate. See the support policy.
hono is a peer dependency on purpose. If your lockfile ends up with a nested second copy, instanceof HTTPException checks fail and the c.respond* and c.var.cwbLogger type augmentations don't apply to your app's Context. Deduplicate it if your package manager reports more than one version.
Configure wrangler
The library runs only on Workers and reads configuration from cloudflare:workers when it loads. A typical wrangler.jsonc:
{
"name": "my-api",
"main": "src/index.ts",
"compatibility_date": "2026-01-14",
"compatibility_flags": ["nodejs_compat"],
"vars": {
"NODE_ENV": "production",
"LOG_LEVEL": "info",
"SERVICE_NAME": "my-api"
},
// optional: KV for caching (datasources look for a binding named KV)
"kv_namespaces": [{"binding": "KV", "id": "<your-kv-namespace-id>"}],
// optional: D1 for DrizzleD1Datasource (default binding name DB)
"d1_databases": [
{"binding": "DB", "database_name": "my-api", "database_id": "<your-d1-id>"}
]
}
compatibility_date:2026-01-14or later is the tested configuration. Earlier dates are not tested.nodejs_compat: recommended. The library imports nonode:*modules, but the tests and the example Worker run with the flag, so it is the verified setup.NODE_ENV: onlydevelopment,dev,testorlocalcount as non-production. An unset value orstagingis production, which masks 5xx error messages. See Environment variables.
TypeScript setup
Workers types
The published type definitions reference Workers globals such as D1Database, KVNamespace and ExecutionContext. Generate them with wrangler types (recommended) or install @cloudflare/workers-types.
- bun
- npm
- pnpm
bunx wrangler types
npx wrangler types
pnpm exec wrangler types
This writes worker-configuration.d.ts, including an Env interface for your bindings and vars. Run it again after changing wrangler.jsonc.
Node types from pino
pino's type definitions import Node modules (events, worker_threads). Without Node types, tsc reports errors inside pino.d.ts. Pick one:
- set
"skipLibCheck": true, or - install
@types/nodeas a dev dependency.
{
"compilerOptions": {
"target": "es2024",
"lib": ["es2024"],
"module": "esnext",
"moduleResolution": "bundler",
"strict": true,
"types": ["./worker-configuration.d.ts"], // from `wrangler types`
"skipLibCheck": true // or install @types/node
}
}
The published .d.ts files have been verified with TypeScript 5.9, 6.0 and 7.0 consumers.
Verify the install
Create a minimal Worker and start it:
import {fromHono} from 'chanfana';
import {createApp} from '@ltv/cwb';
export default createApp({
healthCheck: true,
openApi: (app) => fromHono(app, {docs_url: '/docs'}),
});
bunx wrangler dev
curl localhost:8787/health
# {"status":"healthy","timestamp":"2026-09-14T07:21:37.186Z"}
Next, build a real endpoint in the quick start.