Nanoka

Stable 1.6.1 — Thin wrapper over Hono + Drizzle + Zod for Cloudflare Workers + D1.

Nanoka eliminates the wiring ceremony between Hono, Drizzle, and Zod. One model definition becomes your DB schema, TypeScript types, and base validation — while keeping the 20% explicit where it matters.

Quick look

import { nanoka, d1Adapter, t } from '@nanokajs/core'

const app = nanoka(d1Adapter(env.DB))

const User = app.model('users', {
  id:           t.uuid().primary().readOnly(),
  email:        t.string().email().unique(),
  name:         t.string(),
  passwordHash: t.string().serverOnly(),
  createdAt:    t.timestamp().readOnly(),
})

// GET /users — paginated, safe by default
app.get('/users', async (c) => {
  const users = await User.findMany({ limit: 20, offset: 0, orderBy: 'createdAt' })
  return c.json(User.toResponseMany(users))
})

// POST /users — validator derived from the model
app.post('/users', User.validator('json', 'create'), async (c) => {
  const body = c.req.valid('json')
  const user = await User.create(body)
  return c.json(User.toResponse(user), 201)
})

Why Nanoka?

When you use Hono + Drizzle + Zod manually, you end up writing the same field names in three or four places: the Drizzle schema, the Zod validator, the TypeScript type, and sometimes a separate OpenAPI spec. Nanoka makes the model definition the single source of truth and derives the rest.

  • One definition, multiple derivations — DB schema, TypeScript types, create/update validators, and OpenAPI components all come from the same model.
  • Field policies instead of hand-rolling omits — mark a field serverOnly() and it never appears in output; mark it readOnly() and it is excluded from create/update inputs automatically.
  • Hono internalizedc.req.valid('json'), HTTPException, middleware — the full Hono ecosystem works as-is.
  • Drizzle escape hatch always openapp.db gives you raw Drizzle when the abstraction is not enough.
  • No custom migration enginenanoka generate produces Drizzle schema files; diff generation and migration application stay with drizzle-kit and wrangler d1 migrations.

Positioning

Hono Drizzle Nanoka
Routing yes no yes (Hono internalized)
ORM / queries no yes yes (Drizzle internalized)
Migrations no yes yes (generate + hand-apply)
Validation partial (Zod separately) no yes (derived from model)
Cloudflare Workers yes yes yes
Learning curve low medium low

Compared to alternatives

Nanoka RedwoodSDK Prisma
Philosophy API-first / model-first Full-stack React-first ORM only
Router Hono-compatible RedwoodSDK own none
DB escape hatch raw Drizzle Kysely / raw SQL Raw SQL
Primary use case Small APIs fast Full-stack apps DB access layer only

Prisma 7.0 resolved the bundle-size problem and is now Workers-compatible. Nanoka does not compete on bundle size — the difference is the integrated Hono + D1 API-building experience.

Where to next

  • Getting Started — install, define a model, run migrations, serve your first route.
  • Core Concepts — field policies, the 80/20 design, and the Drizzle escape hatch.