Getting Started
This guide will walk you through setting up Durcno in your TypeScript project and defining, migrating, and querying your database schema.
Prerequisites
Before you begin, ensure you have:
- Node.js => 24.12.0 / Bun => 1.2.0 / Deno => 2.7.0
- A PostgreSQL database (Optional)
Installation
Install Durcno using any package manager
- npm
- pnpm
- Bun
- Yarn
npm install durcno@alpha
pnpm add durcno@alpha
bun add durcno@alpha
yarn add durcno@alpha
Setup
Quick Setup with init Command
The fastest way to get started is using the interactive init command:
- npm
- pnpm
- Bun
- Yarn
npm exec durcno init
pnpm exec durcno init
bunx durcno init
yarn durcno init
This command will prompt you to:
- Select a database connector - Choose from
postgres(postgres.js),pg(node-postgres),bun(Bun SQL) orpglite(WASM) - Connection URL/PATH (Default: process.env.DATABASE_URL!) - PostgreSQL/PGLite connection string
- Schema file - Where to create the schema file (Default:
db/schema.ts) - Migrations folder - Where to store migration files (Default:
migrations)
After completion, it generates:
durcno.config.ts- Durcno configurationdb/schema.ts- A starter schema file with an exampleUserstabledb/index.ts- Database query API
Use the --force flag to overwrite existing files.
Manual Setup
Alternatively, you can manually setup Durcno in your project.
1. Create Configuration File
Create a durcno.config.ts file in your project root to define your database connection and project settings:
// durcno.config.ts
import { defineConfig } from "durcno";
import { pg } from "durcno/connectors/pg";
export default defineConfig({
schema: "db/schema.ts", // Path to your schema file
out: "migrations", // Directory for migration files
connector: pg({
dbCredentials: {
url: "postgresql://postgres:password@localhost:5432/myapp",
},
}),
});
Use environment variables for sensitive credentials:
export default defineConfig({
schema: "db/schema.ts",
connector: pg({
dbCredentials: {
url: process.env.DATABASE_URL,
},
}),
});
2. Define Your Schema
Create your schema file with table definitions:
// db/schema.ts
import {
table,
pk,
varchar,
timestamp,
enumtype,
notNull,
unique,
now,
} from "durcno";
export { Migrations } from "durcno";
export const Users = table("public", "users", {
id: pk(),
name: varchar({ length: 255, notNull }),
email: varchar({ length: 255, notNull, unique }),
password: varchar({ length: 255, notNull }),
createdAt: timestamp({ notNull }).default(now()),
});
3. Set Up Database Connection
Create a database client instance:
// db/index.ts
import { database } from "durcno";
import * as schema from "./schema.ts";
import config from "../durcno.config.ts";
export const db = database(schema, config);
Your First Migration
Generate Migration
After defining your schema, generate your first migration:
- npm
- pnpm
- Bun
- Yarn
npm exec durcno generate
pnpm exec durcno generate
bunx durcno generate
yarn durcno generate
This creates a migration folder with:
up.ts- DDL statements to apply the migrationdown.ts- DDL statements to rollback the migration
Apply Migration
Apply the migration to your database:
- npm
- pnpm
- Bun
- Yarn
npm exec durcno migrate
pnpm exec durcno migrate
bunx durcno migrate
yarn durcno migrate
Check Migration Status
View the status of all migrations:
- npm
- pnpm
- Bun
- Yarn
npm exec durcno status
pnpm exec durcno status
bunx durcno status
yarn durcno status
Writing Your First Queries
Now you can start querying your database with full type safety:
Insert Queries
import { db } from "./db/index.ts";
import { Users } from "./db/schema.ts";
// Insert a single user
await db.insert(Users).values({
username: "johndoe",
email: "john@example.com",
password: "password",
});
// Insert multiple users
await db.insert(Users).values([
{
username: "alice",
email: "alice@example.com",
password: "password1",
},
{
username: "bob",
email: "bob@example.com",
password: "password2",
},
]);
Select Queries
// Select all users
const allUsers = await db.from(Users).select();
// Select specific columns
const userNames = await db.from(Users).select({
id: Users.id,
username: Users.username,
});
// With conditions
import { eq } from "durcno";
const users = await db.from(Users).select().where(eq(Users.id, 1n));
Update Queries
import { eq } from "durcno";
// Update user
await db
.update(Users)
.set({ password: "newpassword" })
.where(eq(Users.username, "johndoe"));
Delete Queries
import { eq } from "durcno";
// Delete user
await db.delete(Users).where(eq(Users.username, "johndoe"));
Working with Relations
Define relationships between tables:
// db/schema.ts
import {
table,
pk,
varchar,
bigint,
relations,
many,
one,
notNull,
} from "durcno";
export const Users = table("public", "users", {
id: pk(),
username: varchar({ length: 255, notNull }),
});
// Users relations
export const UsersRelations = relations(Users, () => ({
posts: many(Posts, Posts.authorId),
}));
export const Posts = table("public", "posts", {
id: pk(),
title: varchar({ length: 255, notNull }),
authorId: bigint({ notNull }).references(() => Users.id),
});
// Posts relations
export const PostsRelations = relations(Posts, () => ({
author: fk(Posts.authorId, Users),
}));
Next Steps
Now that you have Durcno set up, you can:
- Learn about Schema definitions for tables, enums, and etc
- Check out Migrations Guide for handling migrations
- Discover Query Builders for building queries
Need Help?
- Report issues on GitHub