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

use-ergo-state

v0.0.3

Published

This library is meant to be a drop-in replacement for `useState` that provides a more ergonomic API for working with state in React.

Readme

🛌 use-ergo-state

This library is meant to be a drop-in replacement for useState that provides a more ergonomic API for working with state in React.

Installation

# npm
npm i use-ergo-state
# yarn
yarn add use-ergo-state
# pnpm
pnpm add use-ergo-state

This package uses the useRef & useState primitive hooks from React, so React is still required as a peerDependency.

Why useErgoState?

React's API for useState has several ergonomic issues from a DX perspective, including but not limited to: the awkwardness of having to reference your variable name twice, and the oddity of destructuring a tuple. It's model also forces the developer to manage and consider stale state on a regular basis. Signal based APIs like @preact/signals-react have been proposed as a solution for this problem. However, utilizing the signal primitive forces us to rethink the mental model of a React application. The useErgoState hook is intended to allow React developers to continue to enjoy the DX benefits of the virtual DOM while still providing some of the benefits seen in signal based APIs like @preact/signals and solid-js.

How it works

The traditional useState hook returns a tuple of two values. The first element in the tuple is the state value for the current render, and the second element in the tuple is a setter for the next state value which also triggers a rerender.

In useErgoState, a single value is returned. That value is a function which can be called to get the current state value, and can also be called with a new state value to set the next state.

useErgoState in a component

Counter

const Counter = () => {
  const count = useErgoState(0);

  return (
    <div>
      <p>Count: {count()}</p>
      <button onClick={() => count(count() + 1)}>Increment</button>
    </div>
  );
};

setInterval with no stale state

const Timer = () => {
  const time = useErgoState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      time(time() + 1); // no stale state!
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return (
    <div>Time: {time()}</div>
  );
}
import { useState } from "use-ergo-state"; // can also be imported as `useState` if you prefer!

const NameInput = () => {
  const firstName = useState("");
  const firstName = useState("");
  // you can still use inline derived state, unlike with signals
  const fullName = `${firstName()} ${lastName()}`;

  return (
    <>
      <label>
        First name
        <input value={firstName()} onChange={e => firstName(e.target.value)} />
      </label>
      <label>
        Last name
        <input value={lastName()} onChange={e => lastName(e.target.value)} />
      </label>
      <p>Full name: {fullName}</p>
    </>
  );
}

Isn't the name useErgoState not very ergonomic?

It isn't. But this package also exports useErgoState as useState if you prefer to just use that name. The useErgoState name is mostly just there to differentiate it from the React's useState and to make auto-importing slightly easier.

Known footguns

Because the value returned by useErgoState acts as both a getter & setter function, the default behavior is to return the current state value when called without any arguments. If you need to manually update the state value to undefined, you must do so by passing () => undefined to the setter function. Otherwise, no state update will occur.

TypeScript support

The useErgoState hook is written directly in TypeScript and is safely typed.

Special thanks to S.js for the inspiration to make this API!