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.