Quick Start
Build a complete application with Postbase in 10 minutes.
What We'll Build
A simple task management API with:
- Users table with authentication fields
- Tasks table with foreign key to users
- Database migrations
- Type-safe queries with the SDK
Step 1: Initialize Project
# Create project directory
mkdir my-task-app
cd my-task-app
# Initialize npm project
npm init -y
# Install dependencies
npm install @postbase/sdk pg dotenv
npm install -D typescript @types/node tsxStep 2: Start Postbase
# Start the daemon (in another terminal)
postbase start
# Create database
postbase db create tasks
# Initialize Postbase config
postbase initThis creates a postbase.toml file:
[project]
name = "my-task-app"
[database]
name = "tasks"
[migrations]
directory = "./migrations"
schema = "public"Step 3: Create Migrations
# Create users migration
postbase migrate new create_usersEdit migrations/YYYYMMDD_create_users.up.sql:
-- Create users table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create index for email lookups
CREATE INDEX idx_users_email ON users(email);Edit migrations/YYYYMMDD_create_users.down.sql:
DROP TABLE IF EXISTS users;# Create tasks migration
postbase migrate new create_tasksEdit migrations/YYYYMMDD_create_tasks.up.sql:
-- Create tasks table
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(50) DEFAULT 'pending',
due_date DATE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create indexes
CREATE INDEX idx_tasks_user_id ON tasks(user_id);
CREATE INDEX idx_tasks_status ON tasks(status);Step 4: Apply Migrations
# Apply all pending migrations
postbase migrate up
# Check status
postbase migrate statusOutput:
Migration Status for tasks (public)
Applied:
✓ 20260125_create_users (applied: 2026-01-25 10:30:00)
✓ 20260125_create_tasks (applied: 2026-01-25 10:30:01)
Pending: 0Step 5: Generate Types
# Generate TypeScript types
postbase types generate \
--database tasks \
--all \
--output ./src/db/types.tsThis creates src/db/types.ts:
export interface Database {
public: {
Tables: {
users: {
Row: {
id: number
email: string
name: string
password_hash: string
created_at: Date
updated_at: Date
}
Insert: {
email: string
name: string
password_hash: string
created_at?: Date
updated_at?: Date
}
Update: {
email?: string
name?: string
password_hash?: string
updated_at?: Date
}
}
tasks: {
Row: {
id: number
user_id: number
title: string
description: string | null
status: string
due_date: Date | null
created_at: Date
updated_at: Date
}
Insert: {
user_id: number
title: string
description?: string | null
status?: string
due_date?: Date | null
}
Update: {
title?: string
description?: string | null
status?: string
due_date?: Date | null
updated_at?: Date
}
}
}
}
}Step 6: Create Database Client
Create src/db/client.ts:
import { createClient } from '@postbase/sdk'
import type { Database } from './types'
export const db = createClient<Database>({
connectionString: process.env.DATABASE_URL ||
'postgresql://postgres:postgres@localhost:5432/tasks',
})Step 7: Build Your Application
Create src/index.ts:
import { db } from './db/client'
async function main() {
// Create a user
const user = await db
.from('users')
.insert({
email: 'alice@example.com',
name: 'Alice',
password_hash: 'hashed_password_here',
})
.returning()
.single()
console.log('Created user:', user)
// Create some tasks
await db.from('tasks').insert([
{ user_id: user.id, title: 'Learn Postbase', status: 'in_progress' },
{ user_id: user.id, title: 'Build an app', status: 'pending' },
{ user_id: user.id, title: 'Deploy to cloud', status: 'pending' },
])
// Query tasks
const tasks = await db
.from('tasks')
.eq('user_id', user.id)
.order('created_at', { ascending: false })
.execute()
console.log('Tasks:', tasks)
// Update a task
await db
.from('tasks')
.eq('title', 'Learn Postbase')
.update({ status: 'completed' })
// Get completed tasks
const completed = await db
.from('tasks')
.eq('status', 'completed')
.execute()
console.log('Completed tasks:', completed)
}
main().catch(console.error)Step 8: Run Your Application
# Run with tsx
npx tsx src/index.tsOutput:
Created user: { id: 1, email: 'alice@example.com', name: 'Alice', ... }
Tasks: [
{ id: 3, title: 'Deploy to cloud', status: 'pending', ... },
{ id: 2, title: 'Build an app', status: 'pending', ... },
{ id: 1, title: 'Learn Postbase', status: 'in_progress', ... },
]
Completed tasks: [
{ id: 1, title: 'Learn Postbase', status: 'completed', ... },
]Step 9: Deploy to Cloud
# Login to Postbase Cloud
postbase cloud login
# Create a project
postbase cloud projects create my-task-app
# Provision staging database
postbase cloud provision staging
# Get connection string
postbase cloud url stagingUpdate your .env:
DATABASE_URL=postgresql://postgres:xxx@xxx.proxy.rlwy.net:12345/my_task_app_staging
Next Steps
- Enable backups for data protection
- Set up PITR for point-in-time recovery
- Add realtime for live updates
- Deploy to production