🪨
damian
Fundamentals

Workflow

Development and deployment steps

Four repeating steps

Damian uses dbmate for executing migrations. The workflow repeats:

  1. Write a migration in SQL
  2. Generate TypeScript types
  3. Run the migration
  4. Write queries

The same command runs migrations locally and in production. No separate dev workflow.


Create migration

npx damian new

Or pass a name:

npx damian new add_posts_table

Creates a file under ./damian/.migrations/ with this structure:

./damian/.migrations/20240101000000_add_posts_table.sql
-- migrate:up


-- migrate:down

Edit migrate:up with your SQL. migrate:down is used by damian rollback.


Generate types

npx damian generate

Reads migrations, applies them to an in-memory database, produces:

  • ./damian/.generated/tables.ts - table definitions for queries
  • ./damian/.generated/typings.ts - shadow type for custom column overrides
  • ./damian/db.sql - SQL dump of current schema (for review and diffs)

Example generated table:

./damian/.generated/tables.ts
import { s, table } from '@damiandb/pg'

enum Schema {
    PUBLIC = "public"
}

export const UsersTable = table(Schema.PUBLIC, "users", {
    id: s.number("integer"),
    name: s.string("text"),
    email: s.string("text"),
    created_at: s.nullable(s.string("timestamp"))
})

Non-NOT NULL columns are automatically wrapped in s.nullable(...).


Apply migration

npx damian migrate

Runs all pending migration files against your database in order.


Write queries

Use generated tables in your queries. See the Usage page for examples.


Deployment

In CI/CD, run generate before build (generates types at compile time), then apply migrations:

npx damian generate
npx damian migrate

Both commands are production-safe. Generate never touches the database. Migrate only applies pending files.


Rollback

Revert the last applied migration:

npx damian rollback

Executes the -- migrate:down block of the most recent migration.

On this page