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

@stone-js/store

v0.8.19

Published

View-engine-agnostic universal store for Stone.js, with SSR hydration built in.

Readme

Stone.js · Store

Application state written once, read by any view engine. Vanilla core, SSR hydration built in, and no knowledge of React, Vue, Svelte or the DOM.

Part of Stone.js, the reference implementation of the Continuum Architecture: write your domain once, and the context (runtime, protocol, caller) applies to it at run time.

  • Agnostic: runs during server rendering, in the browser and in React Native, unchanged.
  • Hydration is not glue: the state the server rendered is adopted before the first render.
  • Request-isolated by default: two visitors rendering at once never see each other's state.
  • A container citizen: reached with useContainer() in a component, injected into a service.

Install

npm i @stone-js/store

Enabling it

Like every Stone.js module, one of two ways.

import { Store, defineStore } from '@stone-js/store'
import { StoneApp } from '@stone-js/core'

@Store({ stores: [defineStore({ name: 'tasks', state: { items: [], filter: 'all' } })] })
@StoneApp({ name: 'my-app' })
export class Application {}
import { defineStoneApp, defineConfig } from '@stone-js/core'
import { defineStore, storeBlueprint } from '@stone-js/store'

export const Application = defineStoneApp({ name: 'my-app' }, [storeBlueprint])

export const AppConfig = defineConfig((blueprint) => blueprint.set('stone.store.stores', [
  defineStore({ name: 'tasks', state: { items: [], filter: 'all' } })
]))

Using it

Every store is registered as store.<name>, so anything with the container reaches it.

// in a component, on any view engine
const tasks = useContainer().make<IStore<Tasks>>('store.tasks')

// in a service, through the constructor
constructor ({ 'store.tasks': tasks }: { 'store.tasks': IStore<Tasks> }) { this.tasks = tasks }
tasks.getState()
tasks.setState({ filter: 'done' })                       // merges, like a component's setState
tasks.setState((s) => ({ items: [...s.items, task] }))   // or from the current state
tasks.select((s) => s.items.length)                      // read a derived value now
tasks.watch((s) => s.items.length, (n) => render(n))     // watch it, told only when it changes
tasks.reset()

watch compares before notifying, which is the difference that matters: a selector building a fresh object is never equal to itself, so a naive subscription re-renders forever. Select values, or pass your own comparison as the third argument.

SSR hydration

Nothing to wire. Stone.js already ships a keyed, XSS-safe snapshot channel, and a store reads its state out of it when it is registered, which is before the first render. Hydrating in an effect afterwards is what produces the flash of empty state that hand-rolled integrations suffer from.

The state is merged over the initial state, so a snapshot written before a key existed still hydrates into a usable state instead of an incomplete one.

This module never imports a view layer: it reads the snapshot through the container, duck-typed. A Vue or Svelte layer registering the same binding gets hydration with nothing to add here.

Request isolation

perRequest defaults to true, and the default is the point. A store held as a process-wide singleton leaks one visitor's state into the next visitor's page during server rendering, and nothing in development reveals it because there is only ever one request at a time. Stone.js gives an ephemeral container per event, so honouring it costs nothing.

defineStore({ name: 'flags', state: { beta: false }, perRequest: false })   // genuinely process-wide

Documentation

Full documentation: stonejs.dev/docs/extensions/store.

License

MIT