---
title: stateMigrations
url: /docs/iac/concepts/resources/options/statemigrations/
---


The `stateMigrations` resource option lets a component author supply an ordered list of callbacks that translate the component's prior state and the state of its children before diffing. Use it when a new component version changes its internal resource structure while preserving existing cloud resources.

> **Applies to custom and component resources.** The `stateMigrations` resource option applies to both [custom resources](/docs/iac/concepts/resources/) and [component resources](/docs/iac/concepts/components/). It is defined on the base resource-options type in every Pulumi SDK.

> **Note:** This API is **experimental** and may change.

Share feedback in the [component state migrations discussion](https://github.com/pulumi/pulumi/discussions/24799).

## Callback API

Each migration callback is a pure function that transforms the saved state of a component and its children into the state expected by a new component version.

Each callback receives the registering component's URN and the prior state of the component and its descendants. It returns a complete replacement state and, when removing or renaming resource URNs, a mapping from each old URN to its successor. Returning no result leaves the state unchanged and allows later callbacks to run.

The prior subtree contains the component itself first and then its descendants in checkpoint resource format. The registering URN can differ from the root's prior URN when Pulumi matches it through an alias. Each callback receives the preceding callback's result.

A changed result must contain the entire replacement subtree, including unchanged resources. Every input URN must either remain in the result or have a successor mapping to a resource in the result, but not both. Multiple removed URNs can map to the same successor.

## Example

Define a migration callback and pass it to a component through the `stateMigrations` option.

<!-- chooser: language -->

<!-- option: typescript -->
```typescript

```typescript
import * as pulumi from "@pulumi/pulumi";

// Shape of pulumi.StateMigrationArgs, shown here for reference.
type StateMigrationArgs = {
urn: pulumi.URN;
oldState: Record<string, any>[];
};

// Shape of pulumi.StateMigrationResult, shown here for reference.
type StateMigrationResult = {
newState: Record<string, any>[];
successors?: Record<pulumi.URN, pulumi.URN>;
};

function migrate(args: pulumi.StateMigrationArgs): pulumi.StateMigrationResult | undefined {
// args.urn identifies the component being registered.
// args.oldState contains the component's prior state and its descendants.
// Return { newState, successors } when the state needs migration.
return undefined;
}

const component = new MyComponent("example", {}, {
stateMigrations: [migrate],
});

```

```

API reference: [StateMigrationArgs](/docs/reference/pkg/nodejs/pulumi/pulumi/interfaces/StateMigrationArgs.html) · [StateMigrationResult](/docs/reference/pkg/nodejs/pulumi/pulumi/interfaces/StateMigrationResult.html).

```

<!-- /option -->

<!-- option: python -->
```python

```python
from typing import Any

import pulumi

# Fields of pulumi.StateMigrationArgs, shown here for reference.
class StateMigrationArgs:
    urn: str
    old_state: list[dict[str, Any]]

# Fields of pulumi.StateMigrationResult, shown here for reference.
class StateMigrationResult:
    new_state: list[dict[str, Any]]
    successors: dict[str, str] | None

def migrate(args: pulumi.StateMigrationArgs) -> pulumi.StateMigrationResult | None:
    # args.urn identifies the component being registered.
    # args.old_state contains the component's prior state and its descendants.
    # Return pulumi.StateMigrationResult(new_state=..., successors=...) when needed.
    return None

component = MyComponent(
    "example",
    opts=pulumi.ResourceOptions(state_migrations=[migrate]),
)

```

```

API reference: [StateMigrationArgs](/docs/reference/pkg/python/pulumi/#pulumi.StateMigrationArgs) · [StateMigrationResult](/docs/reference/pkg/python/pulumi/#pulumi.StateMigrationResult).

```

<!-- /option -->

<!-- option: go -->
```go

```go
// Shape of pulumi.StateMigrationArgs, shown here for reference.
type StateMigrationArgs struct {
URN      pulumi.URN
OldState []map[string]any
}

// Shape of pulumi.StateMigrationResult, shown here for reference.
type StateMigrationResult struct {
NewState   []map[string]any
Successors map[string]string
}

migrate := func(_ context.Context, args *pulumi.StateMigrationArgs) (*pulumi.StateMigrationResult, error) {
// args.URN identifies the component being registered.
// args.OldState contains the component's prior state and its descendants.
// Return &pulumi.StateMigrationResult{NewState: ..., Successors: ...}, nil when needed.
return nil, nil
}

component, err := NewMyComponent(ctx, "example",
pulumi.StateMigrations([]pulumi.StateMigration{migrate}),
)
if err != nil {
return err
}

```

```

API reference: [StateMigrationArgs](https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v3/go/pulumi#StateMigrationArgs) · [StateMigrationResult](https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v3/go/pulumi#StateMigrationResult).

```

<!-- /option -->

<!-- /chooser -->

See the [state migrations guide](/docs/iac/guides/building-extending/components/state-migrations/) for a complete example.

## Behavior

Callbacks run during previews and updates when prior state exists. They must be idempotent and return no result when the state no longer needs migration. They rewrite state without performing provider operations.

Callbacks must preserve managed resource identity, lifecycle safety flags, and secret envelopes. They must not perform Pulumi runtime operations or wait for unresolved outputs.

See [State migrations](/docs/iac/guides/building-extending/components/state-migrations/) for the full contract, restrictions, and complete examples.
```
