db

Connect your database so every request can use it.

BackendServer

What it is

@kitr/db connects your database to the app lifecycle. Describe the connection once with defineDb; the provider opens it at boot, hands it to useDb() everywhere on the server and closes it on shutdown.

It ships no ORM and runs on the server only. For data on the device, use storage.

Install

kitr add db

First time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.

Adds @kitr/db, its provider, config/db.ts and DATABASE_URL in .env.example. Bring your own ORM. Every change.

Quick start

With Drizzle and postgres.js installed (pnpm add drizzle-orm postgres), describe the connection once:

// config/db.ts
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import { defineDb } from '@kitr/db'
import * as schema from '#server/db/schema'

const createDb = () => drizzle(postgres(process.env.DATABASE_URL!), { schema })

/** The client every controller and action gets from useDb<AppDb>(). */
export type AppDb = ReturnType<typeof createDb>

export default defineDb({
  connect: () => createDb(),
  disconnect: (db) => db.$client.end(),
})

Then read it anywhere on the server:

// server/controllers/orders_controller.ts
import type { HttpContext } from '@kitr/api'
import { useDb } from '@kitr/db'
import type { AppDb } from '#config/db'

export default class OrdersController {
  async index({ app }: HttpContext) {
    return useDb<AppDb>(app).query.orders.findMany()
  }
}

Point DATABASE_URL at a running database and run kitr dev. The provider connects at boot and refuses to start if the database is unreachable. Next in the guide: Connect with Drizzle.

Built on

@kitr/db is built on the kitr server lifecycle and container. The database client itself is whichever you bring:

ORM or driver Docs
Drizzle (the guide's examples) orm.drizzle.team
Prisma prisma.io/docs
Kysely kysely.dev
node-postgres node-postgres.com

kitr adds the typed definition, startup validation of DATABASE_URL, the migration check, useDb() and clean shutdown.

Problems it solves

Further reading