Skip to content

Migration Guide

This guide covers migrating from Zustand’s built-in persist() middleware to ursalock’s encrypted document storage.

import { create } from "zustand";
import { persist } from "zustand/middleware";
const useStore = create(
persist(
(set) => ({
notes: [],
addNote: (note) => set((s) => ({ notes: [...s.notes, note] })),
}),
{ name: "my-store" }
)
);
import { create } from "zustand";
// 1. Plain zustand store (no middleware)
const useStore = create((set) => ({
notes: [],
addNote: (note) => set((s) => ({ notes: [...s.notes, note] })),
}));
// 2. Sync via DocumentClient (after auth)
const collection = docClient.collection<AppState>("app-state");
// Pull on init
const docs = await collection.list({ limit: 1 });
if (docs[0]) useStore.setState(docs[0].content);
// Push on change (debounced)
useStore.subscribe((state) => {
debouncedPush(state);
});
persist()ursalock DocumentClient
localStorage (plaintext)Encrypted localStorage + server sync
Automatic via middlewareExplicit sync engine (pull/push)
No auth neededPasskey authentication
Single deviceCross-device via server
No integrity checksHMAC-SHA256 verification

If you have existing data in persist() localStorage:

// Read old data
const oldData = JSON.parse(localStorage.getItem("my-store") ?? "{}");
// Write to encrypted vault
if (oldData.state) {
await collection.create(oldData.state);
localStorage.removeItem("my-store"); // Clean up
}