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

reeflex

v0.0.1

Published

a react state management library

Readme

Introduction

Reeflex is a lightweight library that provides a Redux-like store and hooks for React applications. It is designed to be easy to use and flexible, allowing you to manage your application's state in a predictable and efficient way.

You don't need to use libraries like reselect or redux-thunk with Reeflex. Selectors are memoized out of the box, and asynchronous dispatch capability is built in.

Unlike Redux, you can easily create state stores that are completely independent of each other as well. The application is not nested in a <Provider /> component, and can be "plug and play" anywhere in your application.

You can also easily migrate your existing Redux reducers to Reeflex.

Reeflex is perfect for times when you need React to just...react.

Installation

To install Reeflex, run the following command: npm install reeflex or yarn add reeflex

Quick Start

To use Reeflex, you need to create a store by calling the reeflex function and passing it your initial state and reducer functions. Then, you can use the store's dispatch function to dispatch actions and update the state, and the useStore hook to subscribe to the store and receive updates to the state in your React components. A Reeflex initial state (slices) key entries must match the reducer they map to. Initial state is essentially a representation of all slices of state. These slices can be declared independently, and then later combined.

Here is an example of a simple counter application:

import React from "react";
import { render } from "react-dom";
import reeflex from "reeflex";

const initialState = {
  count: 0
};

const reducers = {
  count: (state = 0, action) => {
    switch (action.type) {
      case 'INCREMENT':
        return state + 1;
      case 'DECREMENT':
        return state - 1;
      default:
        return state;
    }
  };
};

const [ dispatch, useStore ] = reeflex(initialState, reducers);

const Counter = () => {
  const { count } = useStore((state) => state);

  return (
    <div>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
    </div>
  );
};

render(<Counter />, document.getElementById("root"));

API Reference

reeflex(initialState, reducers) Creates a Redux-like store and hooks for React.

Arguments

initialState (Object): The initial state of the store. reducers (Object): An object where the keys are reducer names and the values are reducer functions. Returns An object containing the following properties:

dispatch (Function): A function that dispatches an action or a thunk. useStore (Function): A hook that allows a component to subscribe to the store and receive updates to the store's state. dispatch(actionOrThunk) Dispatches an action or a thunk. Returns void.

actionOrThunk (Object|Function): The action object or thunk to be dispatched.

useStore (selector) A hook that allows a component to subscribe to the store and receive updates to the store's state.

selector (Function): A function that takes the store's state and returns a derived piece of state.
Returns the derived state.

Examples

Asynchronous Actions

To perform asynchronous actions, such as making API calls, you can use the dispatch function inside a thunk. A thunk is a function that can dispatch actions and has access to the dispatch function and the current state of the store as arguments.

Here is an example of an asynchronous action that makes an API call and dispatches success or error actions based on the result:

import { apiCall } from "./api";

const asyncAction = () => (dispatch, getState) => {
  dispatch({ type: "ASYNC_START" });

  return apiCall()
    .then((response) => dispatch({ type: "ASYNC_SUCCESS", payload: response }))
    .catch((error) => dispatch({ type: "ASYNC_ERROR", error }));
};

dispatch(asyncAction());

You can also use the dispatch function inside the thunk to dispatch multiple actions. For example:

const complexAsyncAction = () => (dispatch, getState) => {
  dispatch({ type: "REQUEST_START" });

  return apiCall()
    .then((response) => {
      dispatch({ type: "REQUEST_SUCCESS", payload: response });
      dispatch({ type: "ANOTHER_ACTION" });
    })
    .catch((error) => dispatch({ type: "REQUEST_ERROR", error }));
};

dispatch(complexAsyncAction());

Selectors

You can use the useStore hook to select a derived piece of state from the store's state. A selector is a function that takes the store's state as an argument and returns a derived state.

Here is an example of a selector that selects the todos array from the store's state:

const todosSelector = (state) => state.todos;

const TodosList = () => {
  const todos = useStore(todosSelector);

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

Selectors can also be used to perform more complex transformations on the store's state. For example:

const completedTodosSelector = (state) =>
  state.todos.filter((todo) => todo.completed);

const TodosList = () => {
  const todos = useStore(completedTodosSelector);

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

Redux DevTools

Reeflex can be used with the tooling you already know and love. Simply create a middleware function and pass it to the array of middleware that Reeflex accepts.

import { useEffect } from "react";
import reeflex from "./reeflex";

const sendToDevTools = (newValue, action, next) => {
  if (window.__REDUX_DEVTOOLS_EXTENSION__) {
    window.__REDUX_DEVTOOLS_EXTENSION__.send(action, newValue, next);
  } else {
    next();
  }
};

const initialState = {
  count: 0
};

const reducers = {
  count: (state, action) => {
    switch (action.type) {
      case "INCREMENT":
        return state + 1;
      case "DECREMENT":
        return state - 1;
      default:
        return state;
    }
  }
};

const [dispatch, useStore] = reeflex(initialState, reducers, [sendToDevTools]);

const Counter = () => {
  const count = useStore((state) => state.count);

  return (
    <div>
      <button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
      <div>{count}</div>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>-</button>
    </div>
  );
};