🌐
Code Snippet of the Day — June 29, 2026LocalStorage with Automatic Expiration (TTL) — JavaScript
Vanilla
localStorage never expires. This zero-dependency wrapper adds automatic TTL so stale data self-cleans. Perfect for API response caching, session tokens, and time-limited preferences.
const TTLStorage = (() => {
const PREFIX = "ttl_";
function set(key, value, ttlSec = 3600) {
const wrapped = `${PREFIX}${key}:${ttlSec}`;
localStorage.setItem(wrapped, JSON.stringify({
value,
expiresAt: Date.now() + ttlSec * 1000
}));
}
function get(key) {
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
if (!k?.startsWith(`${PREFIX}${key}:`)) continue;
const raw = localStorage.getItem(k);
if (!raw) continue;
let entry;
try { entry = JSON.parse(raw); } catch { localStorage.removeItem(k); continue; }
if (Date.now() > entry.expiresAt) { localStorage.removeItem(k); continue; }
return entry.value;
}
return undefined;
}
function has(key) { return get(key) !== undefined; }
function gc() {
let cleaned = 0;
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
if (!k?.startsWith(PREFIX)) continue;
const raw = localStorage.getItem(k);
try {
const entry = JSON.parse(raw);
if (Date.now() > entry.expiresAt) { localStorage.removeItem(k); cleaned++; }
} catch { localStorage.removeItem(k); cleaned++; }
}
return cleaned;
}
return { set, get, has, gc };
})();
// Usage:
TTLStorage.set("userProfile", { name: "Alice" }, 300); // 5 min TTL
const profile = TTLStorage.get("userProfile"); // undefined if expired
const cleaned = TTLStorage.gc(); // clean all expired
💡
Every frontend project needs expiring storage — this is the simplest implementation that actually works.