"It worked all through development, then a real user opened the built app and every setting was gone. Welcome to webview storage."
The Trap That Only Shows Up After You Ship
You reach for the web tool you know: localStorage (maybe behind a Zustand persist middleware). In tauri dev it round-trips perfectly — settings save and reload, no problem. Then you build a real .app, sign it, hand it to someone, and on the second launch every value is gone. Nothing in your code changed. The storage layer underneath did.
Why macOS WKWebView localStorage Isn't Durable
Here's the real reason, learned the hard way in Cinder. In dev, your frontend is served from a Vite origin (http://localhost:1420), and that keeps the WebKit data directory warm, so localStorage persists. But inside a bundled, signed macOS .app, the WKWebView data directory can reset between launches under the app's sandbox and signing posture — so localStorage is effectively ephemeral there. It's not a bug you can fix in JS; it's a property of where webview storage lives on macOS.
The Fix: Persist Through Rust
The store plugin sidesteps the whole question. Instead of trusting the webview's storage, it writes JSON through Rust into the app's config directory — on macOS, under ~/Library/Application Support/<your.identifier>/. That survives app restarts and sandbox resets because it's a real file the OS doesn't wipe. The rule that falls out: in a Tauri app, durable settings belong in the store plugin (or another Rust-side persistence path), never in webview localStorage.