🪨 damian
Easy migrations and typesafe queries with raw SQL
No schema DSL. No diff engine. No "push" shortcut. One workflow, from local to production.
Why Damian?
SQL as source of truth
Write SQL → get types. Not the other way around.
One workflow
No 'push', no 'migrate dev', only 'migrate'.
Query safety
Write queries with typesafe helpers and parameterization.
Installation
npm install -D damian && npm install @damiandb/pgpnpm add -D damian && pnpm add @damiandb/pgyarn add -D damian && yarn add @damiandb/pgQuick Example
import { db, sql } from './db'import { UsersTable } from 'tables'const searchParams = { email: "alice@example.com" }// no, this won't cause SQL injectionconst { rows } = await db.query(sql(UsersTable)` SELECT * FROM ${UsersTable} WHERE ${UsersTable.email} = ${searchParams.email}`)// row is typed as { id: number, name: string, email: string }const user = rows[0]import { db, sql } from './db'import { UsersTable } from 'tables'const { cols, row } = UsersTable.createRow({ name: "Alice", email: "alice@example.com" })await db.query(sql` INSERT INTO ${UsersTable} ${sql.tuple(cols)} VALUES ${sql.tuple(row)}`)import { db, sql } from './db'import { UsersTable } from 'tables'const formInput = { name: "Alice Renamed" }await db.query(sql` UPDATE ${UsersTable} SET ${UsersTable.name} = ${formInput.name} WHERE ${UsersTable.id} = ${1}`)import { db, sql } from './db'import { PostsTable } from 'tables'const post = { id: 42 }await db.query(sql` DELETE FROM ${PostsTable} WHERE ${PostsTable.id} = ${post.id}`)