Skip to main content

Version Migration Guide

This guide covers upgrading your Ever Works Template installation, handling database migrations between versions, managing breaking changes, writing and applying migration scripts, and rollback procedures.

Upgrade Workflow Overview

Upgrading the template follows a structured process to minimize risk:

1. Review changelog for breaking changes
2. Back up your database (pg_dump)
3. Create a feature branch for the upgrade
4. Update dependencies (pnpm install)
5. Generate and apply database migrations
6. Run lint, type check, and build locally
7. Test critical paths (auth, payments, content)
8. Deploy to staging / preview
9. Verify staging
10. Deploy to production

Database Migration System

How Migrations Work

The template uses Drizzle ORM with Drizzle Kit for schema migrations. The schema is defined in lib/db/schema.ts and migrations are generated as SQL files into lib/db/migrations/.

Configuration in drizzle.config.ts:

export default {
schema: "./lib/db/schema.ts",
out: "./lib/db/migrations",
dialect: "postgresql",
dbCredentials: {
url: databaseUrl,
},
} satisfies Config;

Migration Commands

CommandPurposeWhen to Use
pnpm db:generateGenerate SQL from schema changesAfter modifying lib/db/schema.ts
pnpm db:migrateApply pending migrations (Drizzle CLI)Before starting the app after changes
pnpm db:migrate:cliApply with verbose loggingFor debugging migration issues
pnpm db:seedPopulate initial dataAfter fresh migration or seed changes
pnpm db:studioVisual database inspectionFor debugging or data review

Migration File Structure

Migrations are stored as numbered SQL files:

lib/db/migrations/
0000_burly_darkstar.sql # Initial schema
0001_add_image_to_users.sql # Add image column
...
0019_add_subscription_renewal_fields.sql
...
0028_tiresome_mauler.sql # Latest migration
meta/
_journal.json # Migration journal

Drizzle tracks applied migrations in drizzle.__drizzle_migrations:

SELECT hash, created_at
FROM drizzle.__drizzle_migrations
ORDER BY created_at DESC;

Generating a New Migration

After modifying lib/db/schema.ts:

# Generate the migration SQL
pnpm db:generate

# Review the generated file
# (check lib/db/migrations/ for the new file)

# Apply to your local database
pnpm db:migrate

Automatic Migrations

The template runs migrations automatically in two places:

Build-time (via scripts/build-migrate.ts):

// Production builds: failure causes build to fail
if (isProduction) {
process.exit(1);
}

// Preview deployments: connection errors are tolerated
if (isConnectionError && !isAuthError) {
process.exit(0); // Allow preview to deploy
}

Runtime (via instrumentation.ts):

export async function register() {
try {
await initializeDatabase(); // Runs migrate then seed
} catch (error) {
if (isProduction) throw error; // Fail fast
// Dev/preview: log and continue
}
}

Migration Safety by Environment

EnvironmentBuild-TimeRuntimeOn Failure
ProductionRequiredFallbackBuild fails / app throws
PreviewConnection errors toleratedActiveLogs warning, app starts
DevelopmentNot usedActiveLogs warning, app starts
CI (non-Vercel)SkippedNot usedN/A

Rollback Procedures

Drizzle Does Not Support Automatic Rollback

Drizzle Kit generates forward-only migrations. To reverse a migration:

Option 1: Manual reverse migration

  1. Identify the problematic migration in lib/db/migrations/
  2. Write reverse SQL manually:
-- Example: reverse adding a column
ALTER TABLE users DROP COLUMN IF EXISTS new_column;
  1. Apply directly to the database:
psql $DATABASE_URL -f reverse-migration.sql
  1. Remove the forward migration file from lib/db/migrations/
  2. Update the Drizzle journal if needed

Option 2: Restore from backup

The safest rollback approach for complex migrations:

# Restore from pre-migration backup
pg_restore -c -d your-db-name pre_migration_backup.dump

# Verify the restored state
pnpm db:migrate:cli # Shows which migrations are applied

Option 3: Revert schema and regenerate

# Revert schema.ts to the previous version
git checkout HEAD~1 -- lib/db/schema.ts

# Generate a new migration that reverses the changes
pnpm db:generate

# Review and apply
pnpm db:migrate

Dependency Updates

Updating Dependencies

# Check for outdated packages
pnpm outdated

# Update all dependencies
pnpm update

# Update a specific package
pnpm update next@latest

Critical Dependencies

These packages require careful testing when upgrading:

PackageRiskNotes
nextHighMajor versions change APIs, routing, config
next-authHighAuth API changes, session strategy
drizzle-orm / drizzle-kitHighSchema API, migration format changes
next-intlMediumRouting and message loading changes
@sentry/nextjsMediumInstrumentation hook compatibility
stripeMediumPayment API versioning
@heroui/reactMediumUI component prop changes
@trigger.dev/sdkMediumJob scheduling API changes

pnpm Overrides

The template uses pnpm overrides in package.json to force consistent versions:

{
"pnpm": {
"overrides": {
"@types/react": "19.2.7",
"@types/react-dom": "19.2.3",
"esbuild": "0.27.0",
"@opentelemetry/api": "1.9.0"
}
}
}

When upgrading React or esbuild, update these overrides to match.

Breaking Changes Checklist

When upgrading between template versions, review each category:

Schema Changes

  • Compare lib/db/schema.ts with upstream for new/modified columns
  • Generate migrations: pnpm db:generate
  • Review generated SQL for destructive operations (column drops, type changes)
  • Apply to a test database first
  • Verify seed compatibility: pnpm db:seed

API Route Changes

  • Check for renamed or removed routes in app/api/
  • Update external integrations and webhook URLs
  • Verify cron endpoint paths still match vercel.json

Configuration Changes

  • Compare .env.example for new or renamed variables
  • Review next.config.ts changes (headers, webpack, plugins)
  • Check vercel.json for cron schedule changes
  • Review drizzle.config.ts for path changes

Authentication Changes

  • Compare auth.config.ts with upstream
  • Verify session strategy compatibility
  • Test OAuth callback URLs
  • Review permission definitions in lib/permissions/definitions.ts

UI and Styling Changes

  • Compare tailwind.config.ts for theme changes
  • Visually inspect key pages
  • Test responsive layouts
  • Verify theme customizations still apply

Step-by-Step Upgrade Process

1. Prepare

# Back up your database
pg_dump -Fc $DATABASE_URL -f backup_pre_upgrade.dump

# Create a feature branch
git checkout -b feature/template-upgrade

2. Merge Upstream

If you track the template as an upstream remote:

git fetch upstream
git merge upstream/main --no-commit

Resolve conflicts, paying attention to:

  • lib/db/schema.ts -- schema changes
  • next.config.ts -- build configuration
  • auth.config.ts -- auth providers
  • package.json -- dependency versions

3. Install and Migrate

pnpm install
pnpm db:generate # Generate any needed migrations
pnpm db:migrate # Apply migrations
pnpm db:seed # Re-seed if needed

4. Verify Locally

pnpm tsc --noEmit  # Type check
pnpm lint # Lint
pnpm build # Full build
pnpm start # Manual testing

5. Test Critical Paths

AreaWhat to Test
AuthenticationLogin, logout, OAuth, session persistence
PaymentsSubscription flows, webhook handling
ContentPage rendering, search, filtering
AdminDashboard access, RBAC enforcement
i18nLocale switching, translation completeness
Background jobsConsole logs for job registration

6. Deploy

  1. Push the feature branch for CI verification
  2. Deploy to staging / preview environment
  3. Run smoke tests on staging
  4. Merge to main for production deployment

Version Compatibility

Node.js

The minimum version is defined in package.json:

{ "engines": { "node": ">=20.19.0" } }

Database

ProviderSupportedNotes
PostgreSQL 14+YesProduction recommended
SupabaseYesWith connection pooling
NeonYesServerless PostgreSQL

Platforms

PlatformStatusNotes
VercelPrimary targetFull cron, preview, and edge support
DockerSupportedStandalone output for containers
Self-hostedSupportedRequires process management

Troubleshooting Upgrades

SymptomLikely CauseSolution
Build failsIncompatible depsRun pnpm outdated, resolve peer conflicts
DB errors on startupUnapplied migrationspnpm db:generate && pnpm db:migrate
Auth brokenProvider config changedCompare auth.config.ts with upstream
Missing translationsNew keys addedCheck messages/ for missing entries
Styling brokenTailwind config changedCompare tailwind.config.ts
Types mismatchSchema updatedRe-run pnpm db:generate