Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Handle Version Upgrades

When you release a new version of your package, users upgrading from older versions may need data migrations — transforming config formats, moving files, or updating store schemas. The version graph defines the migration path between versions.

This is the mechanism for anything keyed to the package version — the data on disk was written by an older release and the new one cannot read it as-is. It runs once per install, covers restoring a backup taken below the current version, and never runs on a fresh install. Work whose answer can differ on the next start belongs in a oneshot instead; see main.md § Choosing Between a Oneshot, an Init, and a Migration.

Solution

Define a VersionGraph with a current version and an array of other (previous) versions. Each version has up and down migration functions. Use IMPOSSIBLE for directions that can’t be migrated. The up migration transforms old config, moves files, or runs storeJson.merge(effects, {}) to apply new zod defaults. Only versions that introduced a migration need entries in the other array — VersionGraph reaches every other prior version on its own.

The latest version always lives in startos/versions/current.ts. You create a new file when the version already in current.ts carries a migration, because a migration stays with the version that introduced it and is never carried forward: rename the existing current.ts to the version it holds (e.g. v2.3.2_1.ts), add that version to other, then write a fresh current.ts carrying the new version and whatever migration it needs of its own. Bump in place only when the outgoing version’s migration is empty. See Versions — When to Create a New Version File.

Reference: Versions · File Models

Examples

See startos/versions/ in: bitcoin-core, cln, lnd, monerod, nextcloud, simplex, tor, synapse