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 🙏

© 2025 – Pkg Stats / Ryan Hefner

riduce

v0.0.27

Published

Get rid of your reducer boilerplate! Zero hassle state management that's typed, flexible and scalable.

Readme

Riduce 👻

Get rid of your reducer boilerplate!

Zero hassle state management that's typed, flexible and scalable.

npm install riduce

Travis (.org) bundle size npm version

Edit Riduce example - MadLibs for Developers

Whether you're using useReducer or redux, reducer boilerplate is tedious to learn, setup and maintain.

What if type-safe state management was quicker, easier and simpler?

Riduce is a library written to be:

  • Strongly-typed, so your state stays predictable
  • Trivial to scale as your state grows more complex
  • Zero hassle, with just two lines of code...

... and one of the 2 lines to setup is an import.

import riduce from 'riduce'

const [reducer, actions] = riduce(initialState)

That's it! Now you've got a type-safe reducer and arbitrary actions, with zero hassle.

Let's see it in use!

🚧 Full documentation for Riduce is under construction - but the API is essentially the same as Redux-Leaves, except riduce replaces the reduxLeaves default export. Currently documented here are indicative examples on setup, usage and customisation. These give quite a lot of information about how the library is used. For more specifics, please consult the Redux-Leaves documentation to see, e.g., the default action creators which create gives access to.

Introductory Example

For a useReducer example, see this CodeSandbox.

For a redux example, you can run this Repl.it.

For more advanced usage of Riduce, see this example.

Below, we'll walk through the introductory Redux example, showing:

  1. Zero hassle setup with 2 lines of code;
  2. Scalable state management with arbitrary actions; and
  3. Typesafe action creators to mirror your state's shape.

Zero hassle setup

Let's imagine we're controlling the state for a museum.

import { createStore } from 'redux'
import riduce from 'riduce' // 1st line: import

const museumState = {
  isOpen: false,
  visitor: {
    counter: 0,
    guestbook: ['richard woz here']
  }
}

const [reducer, actions] = riduce(museumState) // 2nd line: setup
const { getState, dispatch } = createStore(reducer)

And that's it. Those two lines replace all of our reducer boilerplate.

Scalable state management

Continuing on from above, let's:

  1. Open our museum;
  2. Add to the visitor counter;
  3. Sign the guestbook; and
  4. Amend a guestbook entry.

Previously, you might create 4 x reducer branches, action types and action creators.

Riducer gets rid of all that boilerplate.

Now, it's as simple as describing the changes we want to see!

// at `state.isOpen`, create an action to toggle the boolean
dispatch(actions.isOpen.create.toggle())

// at `state.visitor.counter`, create an action to add 5
dispatch(actions.visitor.counter.create.increment(5))

// at `state.visitor.guestbook`, create an action to push a string
dispatch(actions.visitor.guestbook.create.push('LOL from js fan'))

// at `state.visitor.guestbook[0]`, create an action to concat a string
dispatch(actions.visitor.guestbook[0].create.concat('!!!'))

getState()
/*
{
  isOpen: true,
  visitor: {
    counter: 5,
    guestbook: [
      'richard woz here!!!',
      'LOL from js fan'
    ]
  }
}
*/

All this is possible because Riduce's actions gives you loads of convenient action creators out of the box, which you can use liberally throughout your state tree: update, set, filter, reset, and many more...

It's also possible to add your own in, as documented in advanced Riduce usage.

Typesafe action creators

Now we've seen that Riduce is zero-hassle setup for arbitrary action creators without the reducer boilerplate.

It's written in TypeScript, so it's helpfully typed right out of the box as well!

// can we push to a boolean? no!
// ❌ TypeError: (ts 2339) Property 'push' does not exist on type...
actions.isOpen.create.push()

// can we push to an array without an argument? no!
// ❌ TypeError: (ts 2554) Expected 1-3 arguments, but got 0.
actions.visitor.guestbook.create.push()

// can we push a number to an inferred string[]? no!
// ❌ TypeError: (ts 2345) Argument of type '10' is not assignable to parameter of type 'string'.
actions.visitor.guestbook.create.push(10)

// can we push a string to an inferred string[]? yeah, okay then.
// ✅ compiles!
actions.visitor.guestbook.create.push('10')

Get started

You may wish to check out the following:

Advanced Riduce usage includes:

  1. Bundle multiple actions into a single dispatch;
  2. Execute arbitrary reducer logic for extendability;
  3. Add custom reducers for reusability; and
  4. Control action types for debugging (e.g. Redux DevTools).

Have fun adding it to your project!

npm install riduce

🚧 Full documentation for Riduce is under construction - but the API is essentially the same as Redux-Leaves, except riduce replaces the reduxLeaves default export. Currently documented here are indicative examples on setup, usage and customisation. These give quite a lot of information about how the library is used. For more specifics, please consult the Redux-Leaves documentation to see, e.g., the default action creators which create gives access to.