docs/self-hosting/migration.mdx
This guide walks you through migrating your Reactive Resume installation from v4 to v5. The migration process involves setting up a new v5 instance alongside your existing v4 instance, then transferring your users and resumes to the new system.
<Info> This page is for **v4 → v5 data migration** only. For normal v5 upgrades, use the [Self-Hosting with Docker](/self-hosting/docker) guide. v5 schema migrations run automatically on app startup. </Info> <Warning> **Keep your v4 instance running** until you have successfully migrated all data to v5 and verified everything works correctly. This ensures you have a fallback in case anything goes wrong during the migration. </Warning>Before starting the migration, ensure you have:
<CardGroup cols={2}> <Card title="Running v4 Instance">Your existing Reactive Resume v4 instance should be running and accessible.</Card> <Card title="New v5 Instance"> A fresh Reactive Resume v5 instance set up and running. Follow the [Self-Hosting with Docker](/self-hosting/docker) guide if you haven't done this yet. </Card> <Card title="Database Access"> Access to both your v4 PostgreSQL database (source) and v5 PostgreSQL database (target). </Card> <Card title="Backup">A recent backup of your v4 database. Always backup before any migration.</Card> </CardGroup>The best migration approach depends on the size of your instance:
<CardGroup cols={2}> <Card title="Manual Migration" icon="hand"> **Best for**: Small instances with a handful of resumes. Uses the built-in Import Dialog to manually convert resumes one at a time. </Card> <Card title="Automated Migration" icon="robot"> **Best for**: Large instances with many users and resumes. Uses migration scripts to batch-process all users and resumes automatically. </Card> </CardGroup>If you have only a few resumes to migrate, the simplest approach is to use the Import Dialog feature in v5.
<Steps> <Step title="Export from v4"> In your v4 instance, go to each resume and export it as JSON. This creates a portable file containing all your resume data. </Step> <Step title="Import into v5"> In your new v5 instance: 1. Log in or create a new account 2. Click **Create Resume** or use the **Import** option 3. Select the **Reactive Resume v4** format 4. Upload your exported JSON file The import process automatically converts the v4 format to v5. </Step> <Step title="Verify and repeat"> Review the imported resume to ensure all data transferred correctly. Repeat for each resume you need to migrate. </Step> </Steps> <Tip> The Import Dialog handles the schema conversion automatically, so you don't need to worry about format differences between v4 and v5. </Tip>For instances with many users and resumes, use the migration scripts to automate the process. The migration happens in two phases: first users, then resumes.
To run the migration scripts, you need the following installed on your host machine:
<CardGroup cols={1}> <Card title="Node.js Runtime"> **tsx** - TypeScript execution environment. Install globally with: ```bash npm install -g tsx ``` </Card> <Card title="Environment Loader"> **dotenvx** (or any tool to load `.env` files). Install globally with: ```bash npm install -g @dotenvx/dotenvx ``` Alternatively, you can use `dotenv`, `direnv`, or export the variables manually. </Card> <Card title="Reactive Resume Source Code"> Clone the Reactive Resume repository to access the migration scripts: ```bash git clone https://github.com/amruthpillai/reactive-resume.git cd reactive-resume vp install ``` </Card> </CardGroup>Create a .env file in the root of the repository with the following variables:
# Connection string to your NEW v5 PostgreSQL database (target)
DATABASE_URL="postgresql://user:password@localhost:5432/reactive_resume_v5"
# Connection string to your OLD v4 PostgreSQL database (source)
PRODUCTION_DATABASE_URL="postgresql://user:password@localhost:5432/reactive_resume_v4"
<Warning>PRODUCTION_DATABASE_URL is used only by these migration scripts. It is not a runtime app variable.</Warning>
The user migration script transfers all user accounts, authentication data, and two-factor settings from v4 to v5.
dotenvx run -- tsx scripts/migration/user.ts
What this script does:
scripts/migration/user-id-map.json) that links old user IDs to new onesExpected output:
⌛ Starting user migration...
📥 Fetching users batch from production database (OFFSET 0)...
📋 Found 1000 users in this batch.
📝 Preparing to bulk insert 1000 users...
✅ Bulk inserted 1000 users in 245.3 ms (avg 0.2 ms/user)
💾 Progress saved at offset 1000
📦 Processed 1000 users so far...
📊 Migration Summary:
Users created: 1000
Accounts created: 1000
Two-factor entries created: 50
Skipped (already exist): 0
⏱️ Total migration time: 1234.5 ms (1.23 seconds)
✅ User migration complete!
After users are migrated, run the resume migration script. This script depends on the user ID mapping created in the previous step.
dotenvx run -- tsx scripts/migration/resume.ts
What this script does:
<Info>Like the user script, the resume migration also saves progress and can be resumed if interrupted.</Info>
Expected output:
⌛ Starting resume migration...
📥 Fetching resumes batch from production database (OFFSET 0)...
📋 Found 2500 resumes in this batch.
📝 Preparing to bulk insert 2500 resumes...
✅ Bulk inserted 2500 resumes in 892.1 ms (avg 0.4 ms/resume)
💾 Progress saved at offset 2500
📦 Processed 2500 resumes so far...
📊 Migration Summary:
Resumes created: 2500
Statistics created: 2500
Skipped (userId not found or already exist): 0
Errors: 0
⏱️ Total migration time: 5678.9 ms (5.68 seconds)
✅ Resume migration complete!
Both migration scripts support graceful shutdown and resume:
scripts/migration/user-progress.json and scripts/migration/resume-progress.json track the current migration statescripts/migration/user-id-map.json maps v4 user IDs to v5 user IDsCtrl+C to stop the migration safely. Progress is saved before exit.After completing the migration:
<Steps> <Step title="Verify data integrity"> Log into your v5 instance and spot-check several user accounts and resumes to ensure data transferred correctly. </Step> <Step title="Test functionality"> - Create a test resume and export it as PDF - Verify social logins work (if configured) - Check that two-factor authentication works for migrated users </Step> <Step title="Update DNS/Proxy"> Once verified, update your DNS records or reverse proxy to point to the new v5 instance. </Step> <Step title="Decommission v4"> After confirming everything works and allowing a grace period, you can safely shut down your v4 instance. </Step> </Steps>The migration scripts handle these conversions automatically.