JavaScript migrations
Create, apply, and maintain repeatable JavaScript schema migrations.
Use JavaScript migrations to version collection structure, initialize settings, and run one-time database changes. Migrations live in pb_migrations by default, can be committed to version control, and run in a transaction when applied.
Before you begin
Work from the application directory and keep a disposable development database before testing a downgrade. The JavaScript migration plugin must be registered. --migrationsDir can change the migration directory, and --automigrate is enabled by default in the prebuilt executable.
Start with a clean working tree so the generated file and its schema changes can be reviewed separately. Run the command from the application directory and commit the migrations directory used by the command.
Create and apply a migration
Run ./pocketbase migrate create "add_article_status". The command requires a name and creates a timestamped snake-case file such as pb_migrations/1687801097_add_article_status.js, after confirmation.
Keep one migrate(upFunc, downFunc) call in the file:
migrate((app) => {
app.db().newQuery("UPDATE articles SET status = 'pending' WHERE status = ''").execute()
}, (app) => {
app.db().newQuery("UPDATE articles SET status = '' WHERE status = 'pending'").execute()
})Put forward changes in upFunc and safe reversals in the optional downFunc. Both callbacks receive a transactional app instance.
Start PocketBase with serve to apply unapplied migrations automatically, or run ./pocketbase migrate up. After manual application or reversion, restart serve so cached collections state is refreshed.
Run ./pocketbase migrate down 1 to revert the last migration, or replace 1 with the number of migrations to revert. Verify the resulting schema before restarting the application.
Generate a collection snapshot
Run ./pocketbase migrate collections to generate a migration containing the current collections configuration. It imports in extend mode by default, preserving collections and fields missing from the snapshot. Change the final importCollections argument to true only when the migration is deliberately meant to delete missing collections and fields.
Keep migration history clean
Applied filenames are stored in _migrations. After intentionally squashing or removing intermediate development files, run ./pocketbase migrate history-sync to remove history entries without a related migration file.
Troubleshoot migration history
If migrate create does not produce a file, confirm that the command has a migration name and that the current directory contains the PocketBase application. If migrate up reports an unapplied migration failure, preserve the error and inspect the migration's upFunc against the current schema before retrying. If a file was intentionally removed after squashing, run migrate history-sync so _migrations no longer keeps an entry without a related file.
Continue with collections and data modeling or migrations and schema delivery.