Database
Paperclip uses PostgreSQL via Drizzle ORM. There are three ways to run the database.
1. Embedded PostgreSQL (Default)
Section titled “1. Embedded PostgreSQL (Default)”Zero config. If you don’t set DATABASE_URL, the server starts an embedded PostgreSQL instance automatically.
pnpm devOn first start, the server:
- Creates
~/.paperclip/instances/default/db/for storage - Ensures the
paperclipdatabase exists - Runs migrations automatically
- Starts serving requests
Data persists across restarts. To reset: rm -rf ~/.paperclip/instances/default/db.
The Docker quickstart also uses embedded PostgreSQL by default.
2. Local PostgreSQL (Docker)
Section titled “2. Local PostgreSQL (Docker)”For a full PostgreSQL server locally:
docker compose up -dThis starts PostgreSQL 17 on localhost:5432. Set the connection string:
cp .env.example .envPush the schema:
DATABASE_URL=postgres://paperclip:paperclip@localhost:5432/paperclip \ npx drizzle-kit push3. Hosted PostgreSQL (Supabase)
Section titled “3. Hosted PostgreSQL (Supabase)”For production, use a hosted provider like Supabase.
- Create a project at database.new
- Copy the connection string from Project Settings > Database
- Set
DATABASE_URLin your.env
Use the direct connection (port 5432) for migrations and the pooled connection (port 6543) for the application.
If using connection pooling, disable prepared statements:
export function createDb(url: string) { const sql = postgres(url, { prepare: false }); return drizzlePg(sql, { schema });}Switching Between Modes
Section titled “Switching Between Modes”DATABASE_URL | Mode |
|---|---|
| Not set | Embedded PostgreSQL |
postgres://...localhost... | Local Docker PostgreSQL |
postgres://...supabase.com... | Hosted Supabase |
The Drizzle schema (packages/db/src/schema/) is the same regardless of mode.