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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@noeg/uselocalstorage

v1.0.3

Published

React hooks for handling local storage

Readme

React LocalStorage Hook

A React hook for persisting state in localStorage with TypeScript support and syncing across tabs/windows.

Installation

npm install @noeg/uselocalstorage
# or
yarn add @noeg/uselocalstorage
# or
pnpm add @noeg/uselocalstorage

Features

  • 💾 Persist state in localStorage
  • 🔄 Sync state across tabs/windows
  • 🎯 Same API as useState
  • ⚡️ Optimized performance
  • 🛡️ Type-safe with TypeScript
  • 🧪 Well tested
  • 🌐 SSR friendly

Usage

import { useLocalStorage } from '@noeg/uselocalstorage'

function ThemeToggle() {
  // Works just like useState but persists to localStorage
  const [theme, setTheme] = useLocalStorage('theme', 'light')

  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Switch to {theme === 'light' ? 'dark' : 'light'} mode
    </button>
  )
}

function UserPreferences() {
  // Works with complex objects
  const [preferences, setPreferences] = useLocalStorage('preferences', {
    notifications: true,
    fontSize: 14,
    colorScheme: 'auto',
  })

  // Can use functional updates just like useState
  const toggleNotifications = () => {
    setPreferences((prev) => ({
      ...prev,
      notifications: !prev.notifications,
    }))
  }

  return (
    <div>
      <button onClick={toggleNotifications}>
        Notifications: {preferences.notifications ? 'On' : 'Off'}
      </button>
    </div>
  )
}

API Reference

function useLocalStorage<T>(
  key: string,
  initialValue: T | (() => T)
): [T, (value: T | ((val: T) => T)) => void]

Parameters

| Parameter | Type | Description | | -------------- | ---------------- | ---------------------------------------------------------- | | key | string | The key to store the value under in localStorage | | initialValue | T \| (() => T) | The initial value or a function that returns initial value |

Returns

Returns a tuple of [storedValue, setValue], just like React's useState:

  • storedValue: The current value (from localStorage if available, otherwise initialValue)
  • setValue: A function to update the value (persists to localStorage automatically)

Features in Detail

Lazy Initial Value

You can pass a function as the initial value, which will only be executed once:

const [value, setValue] = useLocalStorage('key', () => {
  // This expensive computation only runs once
  return expensiveComputation()
})

Cross-Tab Synchronization

The hook automatically syncs state across tabs/windows:

function MultiTabDemo() {
  const [count, setCount] = useLocalStorage('count', 0)

  // When you update count in one tab, it updates in all tabs
  return <button onClick={() => setCount((c) => c + 1)}>Count: {count}</button>
}

Type Safety

The hook is fully typed and will infer the correct types from your initial value:

interface User {
  name: string
  age: number
}

// userData and setUserData are properly typed
const [userData, setUserData] = useLocalStorage<User>('user', {
  name: 'John',
  age: 30,
})

Error Handling

The hook handles errors gracefully:

  • Falls back to initial value if localStorage is unavailable
  • Handles JSON parsing errors
  • Works in SSR environments
  • Provides console warnings for debugging

Best Practices

  • Use meaningful keys to avoid conflicts
  • Store minimal necessary data
  • Consider using a prefix for your app's keys
  • Be mindful of localStorage size limits
  • Use JSON-serializable values

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.