load() — no extra code required at call sites.
Why migrations?
Every time you ship a new version of your app that changes the config schema — adding a required field, splitting one field into two, removing a deprecated key — any existing user config on disk is out of date. Migrations let you describe exactly how to transform version N data into version N+1 data. The plugin applies as many steps as needed in sequence, then saves the result back to disk so subsequent loads are already at the current version.How it works
Set a version on your Configurate instance
Pass
version: <number> to the Configurate constructor. This is the current schema version your code expects. The plugin writes this number to a reserved __configurate_version__ key inside every config it saves.Define migration steps
Pass a
migrations array of MigrationStep objects. Each step declares the version it upgrades from and an up function that receives data at that version and returns data at the next version.Call load() as normal
On
config.load(), the plugin reads the stored version number, compares it to the current version, and runs any needed migration steps in ascending order. You do not call migrations manually.MigrationStep interface
up function receives the full config object at version and must return a new object valid at version + 1. You are responsible for returning a new object (or a mutation of the received one) — do not rely on the plugin merging partial results.
If a required migration step is missing (for example, you have data at version 1 but no step with version: 1), the plugin throws an error at load time.
Full example
The following example tracks a config through three versions of a fictional app:- v0 → v1: Added a
fontSizefield that did not exist before. - v1 → v2: Replaced
fontFamily(a free-form string) with a constraineddisplayModeenum.
version: 0 step, then the version: 1 step, saves the result at version 2, and returns the migrated data — all transparently.
Migration rules
| Rule | Detail |
|---|---|
Steps run in ascending version order | The plugin sorts steps by version before applying them, regardless of the order you list them in the array. |
| Each step upgrades exactly one version | A step with version: 1 transforms v1 data into v2 data. There is no support for skipping versions. |
| All intermediate steps must be present | If stored data is at v0 and current version is v3, steps for v0, v1, and v2 must all exist. |
| Migrated data is auto-saved | After migration the updated data is written back to storage so future loads skip migration. |
| Already-current data is not re-saved | If __configurate_version__ in the stored data already equals version, no migration or extra write occurs. |
The __configurate_version__ key
The plugin stores the current schema version in a reserved key named
__configurate_version__ inside your config data. You will see it if you open the raw config file in a text editor. Do not modify or delete this key manually — the plugin uses it to determine whether a migration is needed and which step to start from. If the key is absent, the plugin treats the stored data as version 0.__configurate_version__ in your schema definition; the plugin manages it transparently.