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

@marianmeres/store

v3.0.1

Published

[![NPM version](https://img.shields.io/npm/v/@marianmeres/store.svg)](https://www.npmjs.com/package/@marianmeres/store) [![JSR version](https://jsr.io/badges/@marianmeres/store)](https://jsr.io/@marianmeres/store) [![License](https://img.shields.io/npm/l/

Readme

@marianmeres/store

NPM version JSR version License

Lightweight reactive store implementation with subscriptions and persistence support. Svelte store contract compatible.

Features:

  • Reactive state management with subscriptions
  • Derived stores for computed values (sync and async)
  • Optional persistence to localStorage, sessionStorage, or memory
  • Custom equality (equal) and custom serializers for non-JSON-safe values
  • Re-entrancy-safe set (consistent notification ordering across subscribers)
  • Symbol.dispose support — subscriptions work with using
  • TypeScript support with full type safety
  • Zero dependencies (except pubsub)

Install

deno add jsr:@marianmeres/store
npm install @marianmeres/store

Quick Start

import { createStore, createDerivedStore } from "@marianmeres/store";

// Create a writable store
const count = createStore(0);

// Subscribe to changes (callback is called immediately with current value)
const unsub = count.subscribe(val => console.log(val)); // logs: 0

// Update the store
count.set(1);              // logs: 1
count.update(n => n + 1);  // logs: 2

// Get current value without subscribing
console.log(count.get()); // 2

unsub(); // stop receiving updates

Derived Stores

Create computed values from other stores. A derived store accepts either a single source store or an array of sources:

const firstName = createStore("John");
const lastName = createStore("Doe");

// Single source
const upper = createDerivedStore(firstName, (name) => name.toUpperCase());

// Multiple sources
const fullName = createDerivedStore(
  [firstName, lastName],
  ([first, last]) => `${first} ${last}`
);

fullName.subscribe(console.log); // logs: "John Doe"
firstName.set("Jane");           // logs: "Jane Doe"

Asynchronous derivation (use the set callback — the deriveFn must declare two explicit parameters):

const search = createStore("");
const results = createDerivedStore<Result[]>([search], ([query], set) => {
  fetchResults(query).then(data => set!(data));
}, { initialValue: [] });

Derived stores are lazy: source stores are only subscribed once the derived store itself gains a subscriber. The unsubscribe function returned by subscribe() is idempotent — safe to call multiple times.

Persistence

Automatically persist store values to storage:

import { createStorageStore, createStoragePersistor, createStore } from "@marianmeres/store";

// Simple: auto-persisted store
const prefs = createStorageStore("preferences", "local", { theme: "dark" });
prefs.set({ theme: "light" }); // automatically saved to localStorage

// Advanced: manual persistor with error handling
const persistor = createStoragePersistor<number>("counter", "local");
const counter = createStore(persistor.get() ?? 0, {
  persist: persistor.set,
  onPersistError: (e) => console.error("Storage failed:", e)
});

Storage types: "local" (localStorage), "session" (sessionStorage), "memory" (in-memory Map).

Custom serializers are supported for non-JSON-safe values (Date, Map, Set, BigInt, encrypted payloads, etc.):

const persistor = createStoragePersistor<Date>("when", "local", {
  serialize: (v) => (v as Date).toISOString(),
  deserialize: (s) => new Date(s),
});

Custom equality

By default, set/update notify subscribers only when the new value differs by strict equality (===). Pass a custom equal comparator when you want structural comparison:

const store = createStore({ count: 0 }, {
  equal: (a, b) => JSON.stringify(a) === JSON.stringify(b),
});
store.set({ count: 0 }); // no notification — same shape
store.set({ count: 1 }); // notifies

Resource disposal (using)

The unsubscribe function returned by subscribe() implements Symbol.dispose, so subscriptions can be tied to a block with the using statement (TypeScript ES2024):

{
  using sub = store.subscribe(v => console.log(v));
  // ...work...
} // sub is automatically disposed here

Calling the unsubscribe directly (as a function) continues to work and remains idempotent.

API

See API.md for complete API documentation. See CHANGELOG.md for migration notes between versions.

License

MIT