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

domain-store

v0.1.1

Published

Domain based state store with side effects built in

Readme

npm

domain-store

An experimental Flux style store with native side-effects and a plain javascript API

Installation

yarn add domain-store

or

npm install --save domain-store

Thought Process

redux is great but it has many problems:

  • Some of its big advantages (time-travel, actions timeline) only work when it's committed to 100%
  • Many developers disagree with the number of files (actions, constants, reducers, thunks/sagas/epics) required to do simple tasks, and it's hard to explain the real benefits
  • Actions are meant to be like events, but with middlewares they start to become "come-from" statements where anything can do work at any time and debugging becomes a difficult untangling task
  • As applications grow the number of reducers and middlewares starts to be a performance drag
  • Actions are by their nature fire and forget, which forces you to use the Flux cycle for even very simple tasks ("has my action finished yet?")
  • Debugging can be hard as stacktraces don't link back to their originating component or function call, particularly once side-effect middlewares become involved
  • Side effects require middlewares, which adds extra complexity to manage

domain-store aims to resolve these issues by treating data like enterprise applications have been for years

  • Data is treated as a domain model, with both data and functions attached
  • Both data and actions are still injected into components, which results in great testability and decoupling
  • Less cognitive overhead understanding a 'dispatch pipeline' as 'actions' are just functions which are wrapped by the model
  • Greater performance as functionality is always a direct function call which updates the store
  • All functions are asynchronous, and so don't block up the UI, but the UI can tell when they've finished
  • We can still produce an actions log, as we know the names and domains of functions and their data, and domain-store wraps them internally
  • Very small API surface area
  • Stacktraces always link back to the original caller

The API

import { createModel, createDomain } from "domain-store"

// a model is the root store
// it has many domains, provided as an object
const model = createModel({
  counter: createDomain(
    
    // initial state for the domain
    { count: 0 }, 

    // A factory function which provides store access to domain functions.
    // Functions can get the current state for their domain and 
    // then return a new state, much like a reducer, but with support for side-effects.
    // Async/Promises are supported, and all functions become asyncronous
    (store, deps) => ({
      increment: async () => {
        await deps.doSomeAsyncWork()
        const { count } = store.getState()
        return { count: count + 1 }
      },
      decrement: () => {
        const { count } = store.getState()
        return { count: count - 1 }
      },
    }),

    // You might also want to inject dependencies into your functions.
    // If you provide a dependencies object then you will simply be  
    // passed it as a second argument in the functions creator.
    // This is fantastic for decoupling your functions from 3rd party 
    // libraries which you want to easily mock, and saves the need for stubbing
    {
      doSomeAsyncWork: async () =>  await Promise.resolve('ok')
    }
  )
})

// model now contains:
// model.store { getState(), setState() }
// model.functions { counter: { async increment(), async decrement() } }
// model.addEventListener(callback)

This is just the core package, and the API is designed to allow for framework-specific bindings, just like redux provides.

For instance react-domain-store is already available