Browser storage that evolves with your app. valistorage wraps localStorage and sessionStorage with versioning and migrations — so you can change data shapes without breaking returning users.
Versioned by design
Every storage entry carries a version number. When you ship a new schema, bump the version — the library knows the stored data is from an older generation and handles it accordingly.
Automatic migrations
Define upgrade paths from one version to the next. When a user opens the app with stale data, migrations run on read — old fields map to new ones without manual cleanup code scattered across your codebase.
Typed and validated
Describe your data with TypeScript, then validate at runtime with any schema library — Zod, Yup, Valibot, or your own. TypeScript disappears after compile; validation catches corrupted or unexpected values before they reach your app logic.
localStorage or sessionStorage
Pick the backing store per key. User preferences in localStorage, session state in sessionStorage — same API, same versioning model.
Safe defaults
If data fails validation or no migration path exists, stale entries are removed by default — better than silently serving broken state. Prefer to keep old data until a migration lands? Turn that off with autoRemove: false.
Architecture
valistorage is a thin wrapper around the browser Storage API: each key stores a versioned envelope, migrations transform data on read, and validators guard both stored values and migration output. No global state, no framework lock-in — create a storage instance per domain object and use get, set, and remove like a typed map.
Why I built it
Every app that persists client-side data eventually changes its shape. Raw localStorage gives you JSON strings and hope. I wanted something closer to database migrations — explicit versions, upgrade functions, and validation — without pulling in a full state management library.