create-fedi-app
Modules

database

Optional module — Drizzle ORM CRUD demo with Turso (libSQL) or Supabase (Postgres) selected at scaffold time.

Adds a persistence layer with Drizzle ORM. Driver files differ by database choice at CLI prompt — Turso or Supabase.

Files added

FilePurpose
lib/db/index.tsDatabase client (Turso or Supabase variant)
lib/db/schema.tsDrizzle schema
drizzle.config.tsDrizzle Kit configuration
drizzle/0000_initial.sqlInitial migration
env.tsExtended with DATABASE_URL validation
app/demo/database/page.tsxCRUD demo UI
app/api/items/route.tsREST endpoints for items

Dependencies

  • drizzle-orm, drizzle-kit
  • Turso: @libsql/client
  • Supabase: postgres, @supabase/supabase-js

Environment variables

KeyRequiredDescription
DATABASE_URLyeslibsql://... (Turso) or postgresql://... (Supabase)
DATABASE_AUTH_TOKENTurso onlyTurso auth token

Scripts added

{
  "db:generate": "drizzle-kit generate",
  "db:migrate": "drizzle-kit migrate",
  "db:push": "drizzle-kit push",
  "db:studio": "drizzle-kit studio"
}

Setup

Turso:

turso db create my-fedi-app
turso db show my-fedi-app --url
turso db tokens create my-fedi-app
# Add DATABASE_URL and DATABASE_AUTH_TOKEN to .env.local
bun run db:push

Supabase:

Create a project at supabase.com, copy the Postgres connection string to DATABASE_URL, then:

bun run db:push

Schema

Default demo schema — a simple items table:

export const items = pgTable('items', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
  createdAt: timestamp('created_at').defaultNow(),
});

Turso variant uses SQLite types (sqliteTable, integer).

API routes

MethodPathDescription
GET/api/itemsList all items
POST/api/itemsCreate item { title: string }
DELETE/api/items?id=1Delete by ID

Enhances payment-gated

When combined with payment-gated-content, store payment records in the database instead of in-memory payment-store.ts — migrate the store implementation to Drizzle queries.

Demo route

/demo/database — create, list, and delete items.

See also

On this page