# useLocalStorageWithExpiry > Persisted state with a TTL. - Category: State - Package: `hookli` (install with `npm i hookli`) - Docs: https://hookli.vercel.app/docs/use-local-storage-with-expiry ## Signature ```ts useLocalStorageWithExpiry(key: string, initialValue: T, expiryMs: number): { value: T | null; setStoredValue: (value: T) => void } ``` ## Parameters - `key`: `string` — The localStorage key to read and write. - `initialValue`: `T` — Value used before hydration and when nothing is stored under the key. - `expiryMs`: `number` — Time-to-live in milliseconds. Every write stores the value with a fresh expiry timestamp. ## Returns - `value`: `T | null` — The stored value, or null once the item has expired. Expiry is checked when the hook reads — on mount or key change — at which point the item is removed. - `setStoredValue`: `(value: T) => void` — Persists the value to localStorage with a new expiry of now + expiryMs. ## Usage ```tsx import { useLocalStorageWithExpiry } from "hookli"; export function Demo() { const { value, setStoredValue } = useLocalStorageWithExpiry( "draft", "", 10_000, ); return (

{value === null ? "Expired" : value || "Nothing stored"}

); } ``` ## Source `src/hooks/useLocalStorageWithExpiry.hook.ts` ```ts import { useEffect, useState } from "react"; export const useLocalStorageWithExpiry = ( key: string, initialValue: T, expiryMs: number, ) => { const read = (): T | null => { if (typeof window === "undefined") return initialValue; const raw = window.localStorage.getItem(key); if (!raw) return initialValue; try { const item = JSON.parse(raw); if ( item && typeof item.expiry === "number" && Date.now() > item.expiry ) { window.localStorage.removeItem(key); return null; } return item.value; } catch { return initialValue; } }; const [value, setValue] = useState(initialValue); useEffect(() => { setValue(read()); }, [key]); const setStoredValue = (newValue: T) => { setValue(newValue); if (typeof window === "undefined") return; const item = { value: newValue, expiry: Date.now() + expiryMs }; window.localStorage.setItem(key, JSON.stringify(item)); }; return { value, setStoredValue }; }; ```