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

dedux

v2.0.0

Published

Tiny library, based on the ideas of redux, but with fewer options and less extensibility, but also with less overhead.

Downloads

23

Readme

Dedux

Tiny library, based on the ideas of redux, but with fewer options and less extensibility, but also with less overhead.

The goal is to create a single store, that keeps track of state. The store can notify subscribers of changes to state.

There are three important concepts for this library.

actions

The action is a function to which you can subscribe. Running the action will notify subscribers with the provided argument.

Dedux actions are created by running the createActions function. It takes an array of action names, and returns an object with the names as properties and the action functions as values.

import { createActions } from 'dedux';

const actions = createActions(['firstAction', 'secondAction']);
actions.firstAction.subscribe(payload => {
  console.log(payload);
});
actions.firstAction('hello'); // will log hello

modifiers

A modifier is an object containing pure functions that return a small part of the state.

Modifiers are combined into one object by running the combineModifiers function. It takes an object, with all modifiers as values. The keys will later be used to divide the state into different parts.

store

The store keeps track of a state object. It exposes two functions.

  • subscribe: Will run the provided callback with the latest state whenever it changes. Returns an unsubscribe function.
  • getState: Returns the current state.

When created, the store will set up subscriptions for the provided actions. Whenever an action is run, the store will look for modifiers with the same name, and run them to modify the state. The store will also run any modifier called initialState, to use as a base.

There is also an option to provide an existing initial state object. This is useful when server rendering, or when reloading from local storage or similar.

examples

Todo MVC

Riot TodoMVC, adaptation of existing riot TodoMVC app, to show dedux structure...

complete riot based app

riot-spa-example - Shows some suggestions for structuring, as well as rendering client/server with shared state and routes.

basic sync use case

import { combineModifiers, createActions, createStore } from 'dedux';

const modifiers = combineModifiers({
  menu: {
    initialState: () => ({ menuOpen: false }),
    toggleMenu: (state, payload) => ({ menuOpen: payload })
  }
});

const actions = createActions(Object.keys(modifiers));

const store = createStore(modifiers, actions);

store.subscribe(state => {
  // do something intersting here, like re-rendering a view
  console.log(state);
});

actions.toggleMenu(true);
// will log { menu: { menuOpen: true } }

basic async use case

import { combineModifiers, createActions, createStore } from 'dedux';

const modifiers = combineModifiers({
  customers: {
    initialState: () => ({ customers: [], isLoading: false }),
    fetchCustomers: () => ({ isLoading: true }),
    fetchCustomersSuccess: (state, payload) => ({ isLoading: false, customers: payload }),
    fetchCustomersError: (state, payload) => ({ isLoading: false, error: payload })
  }
});

const actions = createActions(Object.keys(modifiers));

const store = createStore(modifiers, actions);

actions.fetchCustomers.subscribe(() => fetch('/customer')
  .then(actions.fetchCustomersSuccess)
  .catch(actions.fetchCustomersError));

store.subscribe(state => {
  console.log(state.customers);
});

actions.fetchCustomers();
// will log { customers: [], isLoading: true }
// and eventually if successful { customers: [/*data*/], isLoading: false }

on chain of listeners completed

Any action will return the values of its listeners in an array. Given that these values could be promises, we can use Promise.all to be notified when all handlers have completed.

Promise.all(actions.fetchCustomers())
  .then(results => {
    console.log(results);
  });

the name...

... is very much up for debate, just went with the current -ux trend....

TODO

  • more documentation
  • more examples

License

ISC