# Migration Guide

## From Redux-undo

Redux-undo stores whole state snapshots. Travels stores JSON Patch entries.

1. Keep your existing reducer or state updater as the source of state changes.
2. Create a Travels instance with the reducer state.
3. Replace `UNDO` / `REDO` dispatches with `travels.back()` / `travels.forward()`.
4. Use `metadata` labels for undo menu text.
5. Persist with `travels.serialize()` instead of storing the whole Redux-undo history object.

Snapshot stacks can still be better for small state and short local-only history. Travels is strongest when serialized history size matters.

## From Zundo

Zundo integrates directly with Zustand stores. Travels can be used as a separate history engine:

1. Keep Zustand as the UI store.
2. Call `travels.setState(...)` inside store actions.
3. Sync `travels.getState()` back into Zustand after state changes.
4. Use `Travels.deserialize(...)` and the `history` option for persisted history.

See [`examples/zustand.ts`](../examples/zustand.ts).

## From use-travel

`use-travel` is a React hook wrapper. Use Travels directly when you need framework-agnostic control, persistence adapters, metadata, or custom store integration.

1. Create `const travels = createTravels(initialState)`.
2. Subscribe with `useSyncExternalStore`.
3. Expose `travels.getControls()` to components.
4. Use `serialize()` / `Travels.deserialize()` for reloads.

See [`examples/react-integration.tsx`](../examples/react-integration.tsx).

## Persistence Migration

Older hand-rolled persistence usually saved `{ state, patches, position }`. Convert it with `migrate`:

```ts
const history = Travels.deserialize(stored, {
  migrate(snapshot) {
    if (snapshot && typeof snapshot === 'object' && !('version' in snapshot)) {
      return {
        version: 1,
        state: snapshot.state,
        patches: snapshot.patches,
        position: snapshot.position,
      };
    }

    return snapshot;
  },
});
```
