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

use-json-localstorage

v1.4.1

Published

JSON local storage for React

Readme

use-json-localstorage

A tiny, React 18+ safe localStorage utility built on top of useSyncExternalStore.

Most useLocalStorage hooks rely on useEffect + useState, which can be unsafe in concurrent rendering. This library follows the official React pattern for subscribing to external stores.


Why

React 18 introduced concurrent rendering. In this environment, the common pattern below is no longer safe:

useEffect(() => {
  store.subscribe(setState);
}, []);

This can lead to:

  • tearing (inconsistent state during render)
  • unexpected double renders in Strict Mode
  • subtle bugs that are hard to reproduce

React provides a solution for this exact problem:

useSyncExternalStore

use-json-localstorage is a small abstraction that applies this API to localStorage.


Features

  • ✅ React 18+ safe (useSyncExternalStore)
  • ✅ JSON-based persistence (via superjson)
  • ✅ Subscribable localStorage updates
  • ✅ Type-safe API
  • ✅ Tiny & opinionated

Non-goals

This library does NOT aim to be:

  • a global state manager (Redux, Zustand, etc.)
  • an ORM or database abstraction
  • a complex query engine
  • a replacement for server-side persistence

It is intentionally small.


Install

npm install use-json-localstorage

React 18 or higher is required.


Basic Usage

import { useLocalStorageValue } from 'use-json-localstorage';

function Counter() {
  const count = useLocalStorageValue('count', 0);

  return <div>{count}</div>;
}
  • count is read from localStorage
  • updates are subscribed via useSyncExternalStore
  • React always receives a consistent snapshot

Writing Values

import { getRuntimeLocalStorage } from 'use-json-localstorage';

getRuntimeLocalStorage().set('count', 1);

All subscribers of the same key will be notified.


Supported Data Types

Serialization is handled by superjson, which means the following are supported:

  • Object
  • Array
  • Date
  • Map
  • Set
  • BigInt

How It Works

At a high level:

  1. localStorage is wrapped as an evented external store
  2. React subscribes via useSyncExternalStore
  3. Updates trigger a re-render using a fresh snapshot
localStorage
   ↓
event emitter
   ↓
useSyncExternalStore
   ↓
React render

This follows the same pattern used internally by modern state libraries.


Example: Mutation-style Update

getRuntimeLocalStorage().set('user', {
  id: '1',
  name: 'Dohyeon',
});

You can build schema-based mutation helpers on top of this primitive.


SSR

This library is client-only.

  • No SSR persistence
  • No server synchronization

License

MIT


Motivation

This project was created to explore:

  • React 18 concurrency-safe patterns
  • External store design
  • A minimal, explainable alternative to ad-hoc useLocalStorage hooks

If you are building UI infrastructure or headless utilities, this pattern may be useful.


Credits

Inspired by the React 18 RFC and the design of modern state libraries.

License

MIT