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

@abuhasanrumi/state-sync

v1.0.1

Published

A tiny library (1kb) to sync state across browser tabs/windows

Readme

A tiny (~1KB) JavaScript utility to sync state across browser tabs and windows using BroadcastChannel with a localStorage fallback. Perfect for SPAs, PWAs, and collaborative apps needing seamless, real-time updates.

Installation

npm install @abuhasanrumi/state-sync

Live Demo

Check it out:

Live Demo on CodeSandbox

Open the demo in multiple tabs to see a todo list sync instantly!

Usage

Create a reactive state that syncs across tabs:

import { syncState } from '@abuhasanrumi/state-sync'

const state = syncState({
  key: 'counter',
  initialState: { count: 0 },
  persist: true,
  onChange: (state) => console.log('State:', state)
})

state.count += 1 // Updates all open tabs

Options

  • key (string): Unique identifier for the state.
  • initialState (object/array): Initial state to sync.
  • persist (boolean, optional): Save state to localStorage (default: false).
  • onChange (function, optional): Callback triggered on state changes.

Example: Todo List

Build a synced todo list:

import { syncState } from '@abuhasanrumi/state-sync'

const todos = syncState({
  key: 'todos',
  initialState: [],
  persist: true,
  onChange: (state) => {
    document.getElementById('list').innerHTML = state
      .map((todo) => `<li>${todo}</li>`)
      .join('')
  }
})

document.getElementById('add').onclick = () => {
  const input = document.getElementById('input')
  if (input.value.trim()) {
    todos.push(input.value.trim())
    input.value = ''
  }
}

// Initial render
document.getElementById('list').innerHTML = todos
  .map((todo) => `<li>${todo}</li>`)
  .join('')

Notes

  • initialState must be an object or array. For primitives (numbers, strings), wrap them:
    const count = syncState({ key: 'count', initialState: { value: 0 } })
    count.value += 1
  • Nested updates require replacing properties:
    state.nested = { ...state.nested, prop: value }
  • Persisted state must match initialState type, or clear localStorage[key].

Error Handling

  • Throws Error('initialState must be object/array') if initialState is null, undefined, or a primitive.
  • Warns in console if persisted state fails to parse.

Why I Built This

I wanted to tackle a common web dev challenge: keeping state consistent across browser tabs. Whether it’s a shared shopping cart, a live form, or a collaborative tool, users expect tabs to stay in sync without lag or complexity. I created state-sync to deliver that experience in a lightweight ~1KB package, using browser-native APIs to keep it fast and dependency-free.

Why It’s Different Than Others

Unlike heavy state management libraries like Redux or Zustand, or sync solutions like y-js and localforage, state-sync is hyper-focused on cross-tab synchronization. At just ~1KB, it’s a fraction of the size of alternatives, leveraging BroadcastChannel for instant updates and localStorage for broader compatibility. It’s not a full store—just a minimal, reactive utility with TypeScript support, designed to slot into any project without bloat.

Why I Came Up With This Idea

While working on single-page apps, I noticed how often tabs fall out of sync—think adding a todo in one tab but not seeing it in another. Browser APIs like BroadcastChannel offered a solution, but I couldn’t find a simple, tiny library to harness them. After prototyping a todo list that synced across tabs, I was hooked on the idea of making tab-syncing effortless. That spark led to state-sync, a micro-tool to bring that magic to every developer.

Features

  • Lightweight: ~1KB, smaller than most scripts.
  • Real-Time: BroadcastChannel for instant sync, localStorage fallback for compatibility.
  • Reactive: Proxy-based state updates.
  • Persistent: Optional localStorage to retain state.
  • TypeScript-Ready: Full type definitions.
  • Zero Dependencies: Pure JavaScript, built for browsers.

Development

Get started:

git clone https://github.com/abuhasanrumi/state-sync.git
cd state-sync
npm install
npm test
npm run build

Contributing

Have ideas to make state-sync even better? Please:

  1. Fork the repo.
  2. Create a branch: git checkout -b feature/cool-idea.
  3. Commit changes: git commit -m 'Add cool idea'.
  4. Push: git push origin feature/cool-idea.
  5. Open a Pull Request.

License

MIT © Abu Hasan Rumi

Related

Check out my other micro-utility: