npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kushalst/local-storage-expiry

v0.1.2

Published

A vanilla TypeScript wrapper for localStorage that adds TTL and lightweight XOR+Base64 obfuscation.

Readme

local-storage-expiry

Vanilla TypeScript wrapper for localStorage that adds:

  • TTL (Time-To-Live) expiration per key
  • Lightweight obfuscation (Unicode-safe XOR + Base64) so values aren’t stored as plain JSON

This package has zero runtime dependencies.

Install

npm i @kushalst/local-storage-expiry

Quick start

import {
  set,
  get,
  remove,
  flushExpired,
  clear,
} from "@kushalst/local-storage-expiry";

set("myKey", { hello: "world" }, 60_000); // expires in 60s
set("myKeyForever", { hello: "world" }); // persisted (no TTL)
const value = get<{ hello: string }>("myKey");

remove("myKey");
flushExpired();
clear(); // removes only keys created by this library (prefix: lse_)

Key behavior (namespace)

All keys written by this library are stored under the localStorage key:

  • lse_${key}

So:

  • set("token", "abc", 1000) stores under lse_token
  • set("token", "abc") stores under lse_token (no TTL)

This also means:

  • clear() removes only keys starting with lse_ (it won’t touch other app keys)

API

All functions automatically apply the lse_ prefix.

set(key, value, ttlInMs?)

Store a value that expires after ttlInMs milliseconds. If ttlInMs is omitted, the value is persisted (never expires).

set("profile", { id: 123, name: "Kushal" }, 5 * 60_000);
set("profile", { id: 123, name: "Kushal" });
  • key: string (stored as lse_${key})
  • value: unknown (must be JSON-serializable)
  • ttlInMs: number (milliseconds, optional)

Notes:

  • Expiry is computed using Date.now() + ttlInMs.

get<T>(key): T | null

Read a value.

const profile = get<{ id: number; name: string }>("profile");

Returns:

  • The stored value if present and not expired
  • null if missing, expired, or tampered/malformed

Important:

  • If the entry is expired, get() will remove it and return null.
  • If the entry is tampered/malformed, get() will remove it and return null.

remove(key)

Remove a single key (only lse_${key}).

remove("profile");

flushExpired()

Scan all localStorage keys and remove expired lse_ entries.

flushExpired();

Behavior:

  • Only keys starting with lse_ are considered
  • Expired entries are deleted
  • Malformed/tampered entries are also deleted (to keep storage tidy)
  • Non-lse_ keys are untouched

clear()

Remove only keys starting with lse_.

clear();

Obfuscation (XOR + Base64)

This library does not store plain JSON in localStorage. Instead it:

  • Serializes { v, e, d } as JSON (v=version, e=expiry epoch ms or null for “no expiry”, d=data)
  • UTF-8 encodes the JSON (so Unicode is safe)
  • XORs bytes with a static internal secret
  • Base64 encodes the result

This provides light obfuscation so data is not casually readable in DevTools.

Security note

This is not encryption and should not be used to protect secrets against a determined attacker. If you need real security, store sensitive data server-side or use proper cryptography and key management.

TTL / time notes

  • Expiration uses the system clock via Date.now().
  • If the device clock changes, expiration behavior changes accordingly.
  • flushExpired() uses a single now = Date.now() snapshot for the entire sweep.

SSR / non-browser environments

This package uses localStorage. In environments where localStorage doesn’t exist (SSR, some Node contexts), calling set/get/remove/flushExpired/clear will throw:

  • "localStorage is not available in this environment."

Common patterns:

if (typeof window !== "undefined") {
  set("k", "v", 1000);
}

Testing

The included test suite uses Vitest fake timers to validate TTL behavior. If you test code that depends on expiration, prefer fake timers + vi.setSystemTime(...) for deterministic tests.

License

MIT