Skip to content

Migration

Shadowfen edited this page Jul 29, 2026 · 2 revisions

A migration updates existing saved variables from an older format to a newer one. As your addon evolves, settings may need to be renamed, moved, combined, or removed. Rather than asking users to delete their saved data, LibSavedVars lets you transform it automatically while preserving their preferences.

Migrations are only performed when the saved variable version is older than the version required by your addon.

When Is a Migration Needed?

Most updates to an addon do not require a migration.

For example, simply adding a new default setting does not require any special handling:

local defaults = {
    enabled = true,
    showTooltips = true,
}

Players who already have saved variables automatically receive the new default value.

A migration is needed only when existing saved data must be modified.

Typical examples include:

  • Renaming settings.
  • Moving settings to a different table.
  • Splitting one setting into several settings.
  • Combining multiple settings into one.
  • Converting values to a new format.
  • Removing obsolete settings.
  • Changing between account-wide and character-specific storage.

Creating a Migration

A migration is associated with a specific version number.

local settings = LibSavedVars:NewAccountWide(
    "MyAddonSavedVariables",
    2,
    nil,
    defaults
)

settings:Migrate(2, function(savedVars)

    savedVars.general = savedVars.general or {}

    savedVars.general.enabled = savedVars.enabled
    savedVars.enabled = nil

end)

If the player's saved variables are version 1, the migration runs before version 2 is recorded.

If the player is already using version 2 or later, the migration is skipped.

Migration Versions

Each migration targets a specific version.

For example:

settings:Migrate(2, function(savedVars)
    -- Update data for version 2
end)

settings:Migrate(3, function(savedVars)
    -- Update data for version 3
end)

settings:Migrate(4, function(savedVars)
    -- Update data for version 4
end)

When a player upgrades directly from version 1 to version 4, LibSavedVars executes the migrations in order:

  1. Version 2
  2. Version 3
  3. Version 4

Each migration builds on the previous one, ensuring the saved variables reach the current format regardless of how many versions were skipped.

Example: Renaming a Setting

Suppose version 1 stored:

settings.opacity

Version 2 renames it to:

settings.alpha

The migration simply copies the value and removes the old key.

settings:Migrate(2, function(savedVars)

    savedVars.alpha = savedVars.opacity
    savedVars.opacity = nil

end)

Existing users keep their value automatically.

Example: Moving Data

Suppose version 1 stored:

settings.enabled

Version 2 reorganizes the settings:

settings.general.enabled

The migration becomes:

settings:Migrate(2, function(savedVars)

    savedVars.general = savedVars.general or {}

    savedVars.general.enabled = savedVars.enabled
    savedVars.enabled = nil

end)

After migration, all code uses the new location.

Removing Obsolete Settings

Old settings that are no longer used can simply be removed.

settings:Migrate(3, function(savedVars)

    savedVars.oldSetting = nil
    savedVars.debugMode = nil

end)

This keeps the SavedVariables file clean and prevents outdated data from accumulating.

Account and Character Migrations

LibSavedVars also supports migrating data between account-wide and character-specific saved variables.

For example, an addon may initially store all settings account-wide but later decide that some settings should be unique to each character.

Rather than losing existing data, LibSavedVars can copy or move the values into the new storage location during migration.

These migration helpers are covered in the advanced migration documentation.

Migration Helpers

In addition to custom migration callbacks, LibSavedVars provides helper functions for common migration tasks.

These include operations such as:

  • Moving settings between account-wide and character storage.
  • Renaming settings.
  • Copying settings.
  • Removing obsolete settings.
  • Creating missing paths.

Using these helpers often results in simpler, more readable migration code than manually manipulating tables.


Best Practices

When writing migrations:

  • Make each migration responsible for a single version.
  • Never modify data for future versions within an earlier migration.
  • Write migrations so they can safely run only once.
  • Remove obsolete keys after copying their values.
  • Test migrations using saved variables created by older versions of your addon.
  • Increase the saved variable version only when existing data must change.

Summary

Versioning tells LibSavedVars when saved data needs to be updated. Migrations define how that update is performed.

Together, they allow your addon to evolve without requiring users to reset their settings, making upgrades seamless even across many released versions.

Clone this wiki locally