Open source JavaScript npm

StorageManager.js

localStorage and sessionStorage, upgraded. TTL expiration, LZString compression, namespacing, batch operations, and cross-tab sync. All async, all Promise-based.

npm, CDN, or ES module.

npm / yarn

npm install web-storage-manager-js

ES module

import StorageManager from 'web-storage-manager-js';

CDN

<script src="https://cdn.jsdelivr.net/npm/web-storage-manager-js@1.0.1/StorageManager.js"\\></script>

Four options, sensible defaults.

new StorageManager(useSession?, options?)
OptionTypeDefaultDescription
useSessionbooleanfalseUse sessionStorage instead of localStorage
namespacestring""Prefix prepended to every key to isolate modules sharing an origin
defaultExpirationobject{}Map of { keyName: seconds } for auto-expiry on set()
enableCompressionbooleantrueCompress values via LZString (lazy-loaded from CDN on first use)
// Defaults: localStorage, no namespace, compression on
const store = new StorageManager();

// Namespaced with auto-expiration
const appStore = new StorageManager(false, {
  namespace: 'myApp',
  defaultExpiration: { authToken: 3600, userPrefs: 86400 },
  enableCompression: false,
});

All methods are async.

MethodDescription
set(key, value)Store a JSON-serializable value. Auto-expires if defaultExpiration includes the key.
get(key)Retrieve a value, or null if missing or expired. Expired items removed on read.
remove(key)Delete a key and cancel any pending expiration timer.
has(key)Returns true if the key exists and has not expired.
expires(key, seconds)Set or update the TTL for an existing key.
keys()Array of all keys in the active namespace (without prefix).
getAll()All key-value pairs under the active namespace as a plain object.
batchSet(items)Write multiple { key, value, expiresIn? } pairs at once.
batchGet(keys)Read multiple keys. Returns an object mapping each key to its value or null.
batchRemove(keys)Remove an array of keys in one call.
onChange(key, cb)Register a listener called with (newValue, oldValue) on change, including cross-tab.
offChange(key)Unsubscribe the listener for a key.
cleanup()Scan and remove all expired keys. Called automatically on construction.
clear()Remove all entries from the underlying storage object.

Common real-world cases.

Caching an API response for 5 minutes

const cache = new StorageManager(false, {
  namespace: 'apiCache',
  defaultExpiration: { products: 300 },
});

async function getProducts() {
  if (await cache.has('products')) return cache.get('products');
  const data = await fetch('/api/products').then(r => r.json());
  await cache.set('products', data);
  return data;
}

Cross-tab sync

// Tab A
store.onChange('notifications', (count) => updateBadge(count));

// Tab B — triggers Tab A's listener
await store.set('notifications', 5);

Browser storage without the boilerplate.

MIT licensed. TTL, compression, namespacing, and cross-tab sync out of the box. Related: ResourceLoader.js for dynamic asset loading.

Related paths.