Skip to main content

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 add @ltv/cwb hono chanfana zod
bun 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 add drizzle-orm@~0.45.0
Pin the minor version

@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.

Keep a single copy of Hono

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:

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-14 or later is the tested configuration. Earlier dates are not tested.
  • nodejs_compat: recommended. The library imports no node:* modules, but the tests and the example Worker run with the flag, so it is the verified setup.
  • NODE_ENV: only development, dev, test or local count as non-production. An unset value or staging is 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.

bunx 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/node as a dev dependency.
tsconfig.json
{
"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:

src/index.ts
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.