Migrations & Seeding

Database workflow for development and production — Prisma push, migrate, pgvector setup, and seed scripts

Prisma provides two distinct workflows for applying schema changes to your database — one optimized for development speed, and one for production safety. This page covers both, plus how to set up the pgvector extension and seed your database with test data.

Development Workflow

During development, use prisma db push to apply schema changes instantly. It reads your schema.prisma file, compares it to the current database state, and applies the diff — no migration files, no SQL review.
1

Edit the schema

Open apps/boilerplate/prisma/schema.prisma and make your changes. For example, adding a new field:
prisma
model User {
  // ... existing fields
  bio String? // NEW: User biography
}
2

Push the schema

Apply the change to your local database:
bash
cd apps/boilerplate && npx prisma db push
This command:
  1. Computes the diff between your schema and the database
  2. Generates and runs the necessary SQL (ALTER TABLE)
  3. Regenerates the Prisma client automatically
3

Verify in Prisma Studio

Optionally, open Prisma Studio to inspect the database visually:
bash
pnpm db:studio
This launches a browser-based GUI at http://localhost:5555 where you can browse tables, view records, and edit data.

When to Use db push

ScenarioUse db pushUse migrate
Local prototypingYesNo
Exploring schema designsYesNo
CI/CD pipelineNoYes
Production deploymentNoYes
Team collaboration (shared DB)NoYes
Schema history trackingNoYes

Production Migrations

For production databases, use Prisma Migrate. It creates versioned SQL migration files that are reviewed, committed to Git, and deployed through your CI/CD pipeline.
Create a new migration from your schema changes:
cd apps/boilerplate && npx prisma migrate dev --name add-user-bio
This command:
  1. Computes the schema diff
  2. Generates a SQL migration file in apps/boilerplate/prisma/migrations/
  3. Applies the migration to your local database
  4. Regenerates the Prisma client
The generated migration file looks like:
apps/boilerplate/prisma/migrations/
  20260214120000_add_user_bio/
    migration.sql
-- prisma/migrations/20260214120000_add_user_bio/migration.sql
ALTER TABLE "User" ADD COLUMN "bio" TEXT;

Migration Best Practices

Safe patterns for common changes:
prisma
// Adding an optional field — always safe
bio String?

// Adding a required field with a default — safe for existing rows
role String @default("member")

// Renaming a field — use @map to avoid data loss
displayName String @map("name")

Complete Schema Change Workflow

Common Schema Changes

Adding a New Model

  1. Define the model in schema.prisma (see Adding Your Own Models)
  2. Create a migration: cd apps/boilerplate && npx prisma migrate dev --name add-blog-post
  3. Create a query module in apps/boilerplate/src/lib/db/queries/
  4. Export from apps/boilerplate/src/lib/db/queries/index.ts
  5. Add MSW mock handlers in apps/boilerplate/src/mocks/ with inline mock types
  6. Add test factories in apps/boilerplate/src/test/factories/ for the new model

Adding a Field to an Existing Model

prisma
model User {
  // ... existing fields
  avatarUrl String? // New field — nullable, so no migration issues
}
bash
cd apps/boilerplate && npx prisma migrate dev --name add-user-avatar

Adding a Relation

To connect two models, add a foreign key field and a @relation directive:
prisma
model Comment {
  id        String   @id @default(uuid())
  content   String   @db.Text
  userId    String
  postId    String
  createdAt DateTime @default(now())
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  post      BlogPost @relation(fields: [postId], references: [id], onDelete: Cascade)

  @@index([userId])
  @@index([postId])
}
Remember to add the reverse relation arrays on both User and BlogPost:
prisma
model User {
  // ...
  comments Comment[]
}

model BlogPost {
  // ...
  comments Comment[]
}

Removing a Field Safely

1

Mark the field as optional first

If the field is currently required, make it optional in the first migration:
prisma
// Before
bio String
// After (first migration)
bio String?
2

Deploy and verify

Deploy the first migration. Ensure no application code reads this field as required.
3

Remove the field

In a second migration, remove the field entirely:
prisma
// Remove the line from schema.prisma
bash
cd apps/boilerplate && npx prisma migrate dev --name remove-user-bio
This two-step approach prevents runtime errors if your application code still references the field during deployment.

pgvector Setup

Kit uses the pgvector extension for semantic search in the RAG system. After creating your Supabase database, you need to enable the extension and create the vector search index.
1

Open the Supabase SQL Editor

Go to your Supabase dashboard → SQL EditorNew query.
2

Run the setup script

Copy and run the pgvector setup SQL:
prisma/setup-pgvector.sql
-- ============================================
-- Supabase pgvector Setup for FAQ RAG System
-- ============================================
-- Run this script in Supabase SQL Editor
-- (https://supabase.com/dashboard/project/YOUR_PROJECT_ID/sql/new)

-- 1. Enable pgvector extension
-- This adds vector data type and similarity search operators
CREATE EXTENSION IF NOT EXISTS vector;

-- 2. Verify extension is installed
SELECT
  extname AS "Extension Name",
  extversion AS "Version",
  'Installed successfully' AS "Status"
FROM pg_extension
WHERE extname = 'vector';

-- 3. Create IVFFlat index for fast similarity search
-- IVFFlat: Inverted File with Flat compression
-- Good balance between speed and accuracy for < 1M vectors
-- vector_cosine_ops: Uses cosine similarity (1 - cosine distance)
CREATE INDEX IF NOT EXISTS faq_chunks_embedding_idx
ON faq_chunks
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Lists = 100 is good for ~10K-50K vectors
-- Adjust based on dataset size:
--   < 10K vectors: lists = 50
--   10K-50K: lists = 100
--   50K-100K: lists = 200
--   > 100K: lists = sqrt(row_count)
The IVFFlat index uses lists = 100, which is optimized for 10K–50K vectors. Adjust the lists parameter based on your dataset size:
Vector CountRecommended Lists
< 10,00050
10,000 – 50,000100
50,000 – 100,000200
> 100,000sqrt(row_count)
3

Verify the installation

The script includes verification queries. You should see:
  • The vector extension listed with version 0.5.1 or higher
  • The faq_chunks_embedding_idx index created on the faq_chunks table
  • The embedding column with type USER-DEFINED in the column listing

Seeding

Kit does not ship with a seed file — the database is populated through normal application usage (user signup, Clerk webhooks, payment events). However, you can create a seed script for development and testing.

Creating a Seed Script

Create apps/boilerplate/prisma/seed.ts:
typescript
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  console.log('Seeding database...')

  // Create a test user
  const user = await prisma.user.upsert({
    where: { clerkId: 'user_test_123' },
    update: {},
    create: {
      clerkId: 'user_test_123',
      email: 'test@example.com',
      name: 'Test User',
      tier: 'pro',
      creditBalance: 100.00,
      creditsPerMonth: 100.00,
    },
  })

  console.log(`Created user: ${user.id}`)

  // Create a subscription
  await prisma.subscription.upsert({
    where: { userId: user.id },
    update: {},
    create: {
      userId: user.id,
      customerId: 'cus_test_123',
      subscriptionId: 'sub_test_123',
      productId: 'prod_test_123',
      variantId: 'var_test_123',
      status: 'active',
      currentPeriodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
    },
  })

  console.log('Created subscription')

  // Create sample FAQ chunks (for RAG testing)
  await prisma.fAQChunk.createMany({
    data: [
      {
        content: 'How do I reset my password? Go to the login page and click "Forgot password?".',
        question: 'How do I reset my password?',
        answer: 'Go to the login page and click "Forgot password?" to receive a reset email.',
        category: 'Getting Started',
      },
      {
        content: 'How do I upgrade my plan? Go to Dashboard > Billing and select a new plan.',
        question: 'How do I upgrade my plan?',
        answer: 'Navigate to Dashboard > Billing and click "Upgrade" on the plan you want.',
        category: 'Billing',
      },
    ],
    skipDuplicates: true,
  })

  console.log('Created FAQ chunks')
  console.log('Seeding complete!')
}

main()
  .catch((e) => {
    console.error('Seeding failed:', e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

Configuring the Seed Command

Add the seed configuration to apps/boilerplate/package.json:
json
{
  "prisma": {
    "seed": "npx tsx prisma/seed.ts"
  }
}
Then run it:
bash
cd apps/boilerplate && npx prisma db seed

Resetting the Database

To wipe the database and re-seed from scratch:
bash
# Reset database (drops all tables, re-applies migrations, runs seed)
cd apps/boilerplate && npx prisma migrate reset

# Or push schema and seed separately
cd apps/boilerplate && npx prisma db push --force-reset
cd apps/boilerplate && npx prisma db seed

Troubleshooting

Key Commands Reference

CommandPurposeWhen to Use
cd apps/boilerplate && npx prisma db pushApply schema changes directlyDevelopment, prototyping
cd apps/boilerplate && npx prisma migrate dev --name <name>Create and apply a migrationBefore committing schema changes
cd apps/boilerplate && npx prisma migrate dev --create-onlyCreate migration without applyingCode review before apply
cd apps/boilerplate && npx prisma migrate deployApply pending migrationsCI/CD, production deployment
cd apps/boilerplate && npx prisma migrate resetDrop all tables, re-migrate, re-seedReset local database
cd apps/boilerplate && npx prisma generateRegenerate TypeScript clientAfter any schema change
pnpm db:studioOpen database GUIInspect and edit data
cd apps/boilerplate && npx prisma db pullIntrospect database into schemaReverse-engineer existing DB
cd apps/boilerplate && npx prisma db seedRun seed scriptPopulate development data