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

@jondotsoy/location-hash-storage

v0.3.6

Published

Manage application state directly in the URL hash with a localStorage-like API. Zero dependencies, reactive updates, and perfect for shareable links and bookmarkable state

Readme

@jondotsoy/location-hash-storage

A lightweight storage solution that manages application state directly in the URL hash (window.location.hash). It provides a familiar API inspired by localStorage and sessionStorage, allowing you to store, retrieve, and reactively observe key-value pairs that persist in the browser's address bar.

Features

  • Familiar API: Uses the same interface as localStorage and sessionStorage (getItem, setItem, removeItem)
  • URL-based persistence: Data is stored in the URL hash, making it shareable and bookmarkable
  • Reactive updates: Subscribe to changes with subscribeItem for real-time updates
  • Browser navigation support: Automatically syncs when the hash changes via back/forward buttons
  • Type-safe: Written in TypeScript with full type definitions
  • Zero dependencies: Lightweight implementation with no external dependencies
  • SSR-safe: Gracefully handles server-side rendering environments

Installation

npm install @jondotsoy/location-hash-storage
bun add @jondotsoy/location-hash-storage

Usage

Basic Operations

import { LocationHashStorage } from "@jondotsoy/location-hash-storage";

// Set a value
LocationHashStorage.setItem("theme", "dark");
// URL becomes: #theme=dark

// Get a value
const theme = LocationHashStorage.getItem("theme");
console.log(theme); // 'dark'

// Remove a value
LocationHashStorage.removeItem("theme");
// URL becomes: #

// Multiple values
LocationHashStorage.setItem("user", "john");
LocationHashStorage.setItem("lang", "es");
// URL becomes: #user=john&lang=es

Reactive Updates

Subscribe to changes for specific keys:

// Subscribe to theme changes (callback called immediately + on changes)
const unsubscribe = LocationHashStorage.subscribeItem("theme", (value) => {
  console.log("Theme is now:", value);
  document.body.className = value || "light";
});

// The callback is called immediately with the current value
// and whenever the hash changes (via setItem, removeItem, or browser navigation)

// Stop listening when no longer needed
unsubscribe();

Or listen only to future changes:

// Listen to theme changes (callback only called on changes, not immediately)
const unsubscribe = LocationHashStorage.listenItem("theme", (value) => {
  console.log("Theme changed to:", value);
  document.body.className = value || "light";
});

// The callback is only called when the hash changes
// (via setItem, removeItem, or browser navigation)

// Stop listening when no longer needed
unsubscribe();

API

LocationHashStorage.getItem(key: string): string | null

Retrieves the value associated with the given key from the URL hash.

Returns: The value as a string, or null if the key doesn't exist.

LocationHashStorage.setItem(key: string, value: string): void

Sets the value for the given key in the URL hash.

Parameters:

  • key: The key to store the value under
  • value: The string value to store

LocationHashStorage.removeItem(key: string): void

Removes the key-value pair from the URL hash.

Parameters:

  • key: The key to remove

LocationHashStorage.subscribeItem(key: string, callback: (value: string | null) => void): () => void

Subscribes to changes for a specific key in the URL hash. The callback is called immediately with the current value and whenever the value changes.

Parameters:

  • key: The key to watch for changes
  • callback: Function called with the current/new value

Returns: An unsubscribe function to stop listening to changes

Example:

const unsubscribe = LocationHashStorage.subscribeItem("theme", (value) => {
  console.log("Theme changed to:", value);
});

// Later, stop listening
unsubscribe();

LocationHashStorage.listenItem(key: string, callback: (value: string | null) => void): () => void

Listens to changes for a specific key in the URL hash. Unlike subscribeItem, the callback is not called immediately - it only triggers when the value actually changes.

Parameters:

  • key: The key to watch for changes
  • callback: Function called when the value changes

Returns: An unsubscribe function to stop listening to changes

Example:

// Set initial value
LocationHashStorage.setItem("count", "0");

// Listen for changes (callback won't be called immediately)
const unsubscribe = LocationHashStorage.listenItem("count", (value) => {
  console.log("Count changed to:", value);
});

// This will trigger the callback
LocationHashStorage.setItem("count", "1"); // Logs: "Count changed to: 1"

// Later, stop listening
unsubscribe();

Use Cases

  • Sharing application state via URL
  • Preserving UI state across page reloads
  • Creating shareable links with pre-filled forms
  • Implementing simple routing without a router library
  • A/B testing with URL parameters

How It Works

The library reads and writes to window.location.hash using the URLSearchParams API. It listens to the hashchange event to keep the internal state synchronized with browser navigation (back/forward buttons).

License

MIT © 2025 Jonathan Delgado

Author

Jonathan Delgado - [email protected]