Minimal, namespaced, and typed localStorage wrapper.
Install
pnpm
npm
yarn
Examples
Load or Initialize
const settings = storage.getOrSet("settings", () => ({ theme: "dark", lang: "en", }));
Counters and Read-Modify-Write
storage.update("visits", (n) => n + 1, 0); // 1, then 2, ... storage.update("settings", (s) => ({ ...s, theme: "light" }));
Lists
storage.update("todos", (list) => [...list, { id: 2, text: "Ship it" }], []);
Inspect and Export a Namespace
storage.keys(); // ['settings', 'visits'] storage.keys(true); // ['my-app:settings', 'my-app:visits'] storage.entries(); // [['settings', {...}], ['visits', 3]] Object.fromEntries(storage.entries()); // plain object snapshot storage.size(); // 2
Isolated Namespaces
const auth = new LocalStorageService("auth"); const ui = new LocalStorageService("ui"); auth.set("token", "abc"); ui.set("token", "xyz"); // no collision ui.clear(); // auth:token is untouched
TypeScript
Pass type arguments to type the result:
import { LocalStorageService } from "ls-service"; interface User { id: number; name: string; } const storage = new LocalStorageService("my-app"); storage.set("user", { id: 1, name: "Ada" }); const user = storage.get<User>("user"); // User | null const safe = storage.get<User>("user", defaultUser); // User (fallback given) const theme = storage.getOrSet<string>("theme", () => "dark"); // string const count = storage.update<number>("count", (n) => (n ?? 0) + 1, 0); // number const all = storage.entries<User>(); // [string, User | null][]
The type is a compile-time assertion only; stored data is not validated at runtime, so treat it as untrusted if its shape may have changed between releases.
Error Handling
Storage problems always throw; there is no in-memory fallback.
- Unavailable (SSR, privacy mode, access denied): The constructor throws
STORAGE_UNAVAILABLE, with the original underlying error attached ascause. - Invalid namespace: The constructor throws
STORAGE_NAMESPACE_INVALID. - Quota exceeded / write failure:
set(andgetOrSet/update) throw the standard storage error, e.g.,QuotaExceededError. - Unserializable values (e.g. circular objects):
setthrows aTypeError.
import { LocalStorageService } from "ls-service"; try { const storage = new LocalStorageService("my-app"); storage.set("big", data); } catch (error) { if (error.message.includes("unavailable")) { // localStorage blocked or missing; check error.cause for details } else if (error.name === "QuotaExceededError") { // storage limit reached } else { throw error; } }
API
For more detailed documentation, please view the API Reference.
Contributing
If you have suggestions for how this project could be improved, or want to report a bug, feel free to open an issue! We welcome all contributions.
Likewise, before contributing please read the contribution guide.
Motivation
After implementing this simple service wrapper across several client-side projects, I decided to publish it as a public package rather than repeatedly copying the code.