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

usestand

v1.0.4

Published

A small, fast local state-management solution using simplified redux/flux principles or useState with steroids.

Downloads

25

Readme

Welcome to useStand the useState with steroids

A small, fast local state-management solution using simplified redux/flux principles.

Why?

Redux is a great library, but it's a bit too much for some projects. This library is a simplified version of redux/flux.

Installation

npm install usestand # or yarn add usestand

Create a store

import create from 'usestand';

const useStand = create(({getState, setState}) =>({
    count: 0,
    inc: () => setState(state => ({ count: state.count + 1})),
    dec: () => setState(state => ({ count: state.count - 1})),
}));

Then bind it to your component


function Counter() {
    const { count, inc, dec } = useStand();

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={inc}>+</button>
            <button onClick={dec}>-</button>
        </div>
    );
}

Usage with typescript

Typescript usage is very simples, just add the type of your state to the create function.

import create from 'usestand';

interface State {
    count: number;
    inc: () => void;
    dec: () => void;
}

const useStand = create<State>(({getState, setState}) =>({
    count: 0,
    inc: () => setState({ count: getState().count + 1 }), // direct getState
    dec: () => setState(state => ({ count: state.count - 1})), // getState in callback
}));

Reading state in actions

setState can receive a callback with the current state as parameter, or you can use store to get the current state.

import create from 'usestand';

const useStand = create(({getState, setState}) =>({
    count: 0,
    inc: () => setState(state => ({ count: getState().count + 1})),
    dec: () => setState(state => ({ count: getState().count - 1})),
}));

Async actions

import create from 'usestand';

const useStand = create(({getState, setState}) =>({
    count: 0,
    inc: async () => {
        const lastCount = await getLastCount();
        setState({ count: lastCount + 1});
    },
}));

Equality check

The returned useStand hook as a parameter to check the equality of the state, this is useful when you dont want to re-render the component is some cases.

import create from 'usestand';

const useStand = create(({getState, setState}) =>({
    count: 0,
    myOtherValue: 1,
    inc: () => {
        setState({
            count: 0,
            myOtherValue: Math.Random(),
        });
    },
}));

function Counter() {
    const { count, inc, dec } = useStand((a, b) => a.count === b.count); // only re-render if count changes

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={inc}>+</button>
            <button onClick={dec}>-</button>
        </div>
    );
}

Initial state

If you want to set/reuse/spread the initial state of the store, you can pass it as a second parameter to the create function.

import create from 'usestand';

const useStand = create(({getState, setState, getInitialState}) =>({
    count: 0,
    inc: () => setState(state => ({ count: getState().count + 1})),
    dec: () => setState(state => ({ count: getState().count - 1})),
    reset: () => setState(getInitialState()),
}));

Global State

If you want to share the state between components, you can use the global state using context api.

Fist create hooks and providers
import { createStandContext } from 'usestand';

const [useMyState, MyStateProvider] = createStandContext(({ setState }) => ({
    counter: 0,
    increment: () => setState((state) => ({ counter: state.counter + 1 })),
    decrement: () => setState((state) => ({ counter: state.counter - 1 })),
}));
Then use it in your components

function Counter() {
    const { counter, increment, decrement } = useMyState();

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={inc}>+</button>
            <button onClick={dec}>-</button>
        </div>
    );
}

function Container() {
    return (
        <MyStateProvider>
            <Counter />
        </MyStateProvider>
    );
}

ReactDOM.render(<Container />, document.getElementById('root'));

Global State selectors and equality check

On global state, you can use selectors to get a specific value from the state, and you can use a equality check to avoid unnecessary re-renders.

import { createStandContext } from 'usestand';

const [useMyState, MyStateProvider] = createStandContext(({ setState }) => ({
    counter: 0,
    increment: () => setState((state) => ({ counter: state.counter + 1 })),
    decrement: () => setState((state) => ({ counter: state.counter - 1 })),
}));

function Counter() {
    // get only the counter value and check if the value is the same with string casting so '1' is equal 1 and don't re-render
    const counter = useMyState((s) => s.counter, (a, b) => String(a) === String(b));
    // get only the increment function
    const increment = useMyState((s) => s.increment);
    // get only the decrement function
    const decrement = useMyState((s) => s.decrement);

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={inc}>+</button>
            <button onClick={dec}>-</button>
        </div>
    );
}

function Container() {
    return (
        <MyStateProvider>
            <Counter />
        </MyStateProvider>
    );
}

ReactDOM.render(<Container />, document.getElementById('root'));

buil-in shallowCompare

If you want to use the shallowCompare function, you can import it from usestand. Note: The default equality check is the shallowCompare function.


import { shallowCompare } from 'usestand';

function Counter() {
    const { count, inc, dec } = useStand(shallowCompare);

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={inc}>+</button>
            <button onClick={dec}>-</button>
        </div>
    );
}

Builtin Middlewares 🚧(WIP)

  • [] Builtin persistence middleware
  • [] Builtin logger middleware