localStorage helpers
localStorage access that cannot throw, plus a prefixed JSON view over it.
localStorage is not merely absent under SSR — it also throws on access in a third-party iframe with cookies blocked, and on write in Safari private mode or at quota. Every read and write here is guarded, because a storage failure should degrade a preference, never break the page.
API
localStorageSetItem
Set a value in localStorage.
Parameters
| Parameter | Description | Type | Default |
|---|---|---|---|
name | Key name | string | Required |
value | Value | string | Required |
Return
No return value (void)
localStorageGetItem
Get a value from localStorage.
Parameters
| Parameter | Description | Type | Default |
|---|---|---|---|
name | Key name | string | Required |
Return
| Argument | Description | Type |
|---|---|---|
string | Stored value, returns empty string if not exists | string |
localStorageRemoveItem
Remove a key.
| Parameter | Description | Type | Default |
|---|---|---|---|
name | Key name | string | Required |
createStore(prefix?)
A prefixed, JSON-serialising view over localStorage.
Return
| Method | Description |
|---|---|
get(key, fallback) | Stored value, or fallback when missing, unavailable or corrupt |
set(key, value) | Serialise and store; false when nothing was written |
remove(key) | Remove the key |
keyOf(key) | Full storage key (prefix + key) — useful for storage listeners |
Example
Basic Usage
import { localStorageSetItem, localStorageGetItem } from 'ranuts';
// Set value
localStorageSetItem('username', 'john');
// Get value
const username = localStorageGetItem('username');
console.log(username); // 'john'Store Object
import { localStorageSetItem, localStorageGetItem } from 'ranuts';
const user = { name: 'John', age: 30 };
localStorageSetItem('user', JSON.stringify(user));
const storedUser = JSON.parse(localStorageGetItem('user'));
console.log(storedUser); // { name: 'John', age: 30 }Server-Side Safety
import { localStorageSetItem, localStorageGetItem } from 'ranuts';
// Won't throw error in server-side environment, fails silently
localStorageSetItem('key', 'value'); // Server-side: no operation
const value = localStorageGetItem('key'); // Server-side: returns ''Check Existence
import { localStorageGetItem } from 'ranuts';
const value = localStorageGetItem('myKey');
if (value) {
console.log('Value exists:', value);
} else {
console.log('Value does not exist');
}Namespaced JSON storage
import { createStore } from 'ranuts';
const history = createStore('agent_history_');
history.set('default', messages); // writes agent_history_default
const restored = history.get('default', []); // [] when absent or corrupt
history.remove('default');Several features, one origin
import { createStore } from 'ranuts';
// Prefixes keep unrelated features from colliding.
const keys = createStore('agent_api_key_');
const prefs = createStore('editor_prefs_');
keys.set('anthropic', token);
prefs.set('theme', 'dark');Notes
Nothing here throws. Missing storage, a blocked third-party frame, private mode, quota — all of them degrade quietly.
localStorageGetItemreturns'', the setters do nothing, andcreateStore().set()reportsfalse.Guarded at call time, not module load. The storage lookup happens inside each call, so these work after SSR-then-hydrate and can be stubbed in tests.
createStorevalidates nothing. Whatever was stored comes back typed asT; check it yourself if it crosses a version boundary. The fallback only covers absence and parse failure — a value written by an older version of your code cannot throw aSyntaxErrorinto the caller, but it can still be the wrong shape.setreturnsfalsefor a circular structure, aBigInt, or a write that did not land. It reads the value back to confirm.Type limitation: the raw helpers only handle strings. Use
createStorerather than hand-rollingJSON.stringify/JSON.parsewith a try/catch at each call site.Return value:
localStorageGetItemreturns''when the value does not exist, notnull.