Prisma has two ways to apply schema changes. Use the right one depending on your environment.
Development — db push
db push syncs your schema to the database directly, without creating a migration file. Fast for iteration, not safe for production.
pnpm db:push
Use this when:
- You're iterating quickly and the data doesn't matter yet
- You haven't launched to users
- You're resetting the DB regularly with
pnpm db:reset
db push can drop columns without warning if you rename or remove a field.
Never use it on a production database with real user data.
Production — migrate
migrate dev creates a SQL migration file and applies it. The file is committed to git and applied in production with migrate deploy.
Create a migration
pnpm db:migrate
# Prisma prompts for a name, e.g. "add_onboarding_completed"
This creates prisma/migrations/20240101_add_onboarding_completed/migration.sql and applies it to your local database.
Apply in production
pnpm db:migrate:deploy
# Applies any pending migrations that haven't run yet
Run this in your deployment pipeline — before the app starts. On Vercel, add it to the build command:
# vercel build command
pnpm db:migrate:deploy && pnpm build
Scripts reference
pnpm db:push # sync schema to DB (dev only)
pnpm db:migrate # create + apply migration (dev)
pnpm db:migrate:deploy # apply pending migrations (prod)
pnpm db:studio # open Prisma Studio
pnpm db:reset # drop DB + re-push + seed (dev only)
These are defined in package.json:
{
"scripts": {
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:migrate:deploy": "prisma migrate deploy",
"db:studio": "prisma studio",
"db:reset": "prisma migrate reset --force"
}
}
Workflow for a schema change
Edit the schema
Open prisma/schema.prisma and make your changes — add a field, new model, relation, etc.
Generate the Prisma client
pnpm db:push # dev: apply + regenerate client
# or
pnpm db:migrate # dev: create migration + apply + regenerate clientPrisma regenerates the TypeScript client automatically after every push or migrate.
Update your code
TypeScript will immediately surface any breaking changes — fields you removed, types that changed. Fix them before committing.
Commit the migration file
If you used db:migrate, commit the generated file in prisma/migrations/. This is your audit trail and how production gets updated.
git add prisma/
git commit -m "feat: add onboarding_completed to user"Deploy
Your CI/CD runs pnpm db:migrate:deploy before starting the app. Prisma checks which migrations have already run (tracked in _prisma_migrations) and applies only the new ones.
Better Auth and migrations
Better Auth's tables are defined in schema.prisma alongside your models. When you add a new Better Auth plugin (e.g. twoFactor, passkey), run:
npx better-auth migrate # generates the SQL
pnpm db:migrate # applies it via Prisma
Or add the columns to schema.prisma manually and run pnpm db:push / pnpm db:migrate as usual.
Auth, billing, orgs, and emails — all wired up. Clone and deploy in minutes.
Get launch.now