DEV Community

Cover image for The Simplest Way to Manage State in React
Christian Boffill
Christian Boffill

Posted on

The Simplest Way to Manage State in React

Why I Built use-s-react

I've always liked React's functional style, but when it comes to managing state in the application, things get complicated and whatever alternative you choose, you end up writing the detested boilerplate.

useState is great for local values, but managing shared state across components? That often meant jumping to useContext, Redux, Zustand, or other more complex tools.

It's not just boilerplate, if you want to use a third party library, you also end up having to learn new concepts or approaches to make use of it.

But in many cases, all I wanted was: a simple way to manage local and global state without all the ceremony.


What is useS?

useS is a React hook for managing local and global state through a simple, unified API.

It's powered by useSyncExternalStore under the hood, ensuring consistent and performant state updates—no matter where the component lives.

Here are some of its key features:

  • ✅ API as intuitive as useState
  • ✅ Manage local and global state with a single line
  • ✅ No context, providers, or boilerplate needed
  • ✅ Immutable by default — even for complex objects
  • ✅ Automatic deep comparison to avoid unnecessary renders
  • ✅ Support for declarative derived state
  • ✅ Full TypeScript support
  • ✅ Scalable patterns out of the box

Getting Started with useS

Let’s take a look at how easy it is to get started with useS.

1. Installation

Install it using your favorite package manager (npm page):

npm i use-s-react 
Enter fullscreen mode Exit fullscreen mode

2. Local State (Just like useState)

If you're familiar with useState, you'll feel right at home. Here’s a basic counter:

import { useS } from "use-s-react"; export default function Component() { const [count, setCount] = useS(0); return ( <button onClick={() => setCount(prev => prev + 1)}> You clicked {count} times </button> ); } 
Enter fullscreen mode Exit fullscreen mode

✅ You just used local state — no different from useState

3.Global State (Same line, more power)

Want to share state across multiple components? Just add the config object:

import { useS } from "use-s-react"; export default function Component() { const [count, setCount] = useS({ value: 0, key: 'global-counter' }); return ( <button onClick={() => setCount(prev => prev + 1)}> You clicked {count} times </button> ); } 
Enter fullscreen mode Exit fullscreen mode

Try this line in another component:

const [count, setCount] = useS({ value: 0, key: "global-counter" }); 
Enter fullscreen mode Exit fullscreen mode

🔁 Now this state is global. Any component using the same key will be automatically synced.

That's it

With a single line of code, you can handle both local and global state.
No context, no boilerplate, no custom providers—just a consistent, intuitive API.


Comparing useS with React's Built-in APIs

React gives you full control with primitives like useState, useReducer, and useContext, but composing them for global state often adds friction. Here's how useS compares:

Feature / API React APIs useS
Local state
No Boilerplate (Local) 🟡 Low–Medium
Ease of use (Local) 🟡 Medium 🟢 Easy
Global state
No Boilerplate (Global) 🟡 Medium
Ease of use (Global) 🔴 Hard 🟢 Easy
No Provider Required
Deep comparison
Automatic immutability
Derived state support ⚠️ Manual
TypeScript support
Bundle size ✅ (built-in) 🟢 Small (~1.5 KB)
State persistence ❌ (coming soon)

✅ = Excellent / No boilerplate required , ❌ = Missing feature

🟢 = Great , 🟡 = Acceptable , 🔴 = Verbose / Painful , ⚠️ = Workaround needed

Why useS over plain React APIs?

While React gives you all the primitives to manage state, combining them for global use often leads to excessive boilerplate, complexity, and patterns that don’t scale well.

useS was designed to simplify that experience.

With just one line, you can manage local and global state, skip the boilerplate, and unlock features like automatic immutability, deep comparison, and derived state—all while keeping full TypeScript support and avoiding providers or custom setups.

But useS goes beyond simplicity: it also gives you structure.

By using key-based state definitions, you can organize your application into one centralized store or multiple scoped stores as your architecture demands. Since the global store is just a JavaScript object under the hood, you remain fully in control—no extra abstractions, no black boxes.


My Top 5 State Management Libraries in React (2025 Edition)

After spending the last few years building React apps, testing patterns, and experimenting with different state management strategies, I wanted to take a step back and evaluate the best tools we have available today in 2025.

To be as objective as possible, I created a scoring system based on the following criteria:

  • Local state support
  • Global state support
  • Ease of use
  • Boilerplate required
  • Provider-free usage
  • Deep comparison support
  • Automatic immutability
  • Derived state support
  • TypeScript support
  • Bundle size
  • React 18+ compatibility
  • Web & React Native compatibility
  • Debugging / DevTools integration
  • Built-in persistence
  • Unique architectural advantages

Each library received a score from 0 to 10 per category:

  • 0 means the feature is not present.
  • 4–8 reflects basic or intermediate support.
  • 9–10 means the feature is robust, polished, or exceptionally well-implemented.

Based on that evaluation, here's my personal Top 5 for this year:

Library Overall
useS 9.3
Zustand 8.8
Jotai 8.6
Redux-Toolkit 8.4
Recoil 8.2

A Personal Note

This ranking is not meant to discredit or diminish the incredible work done by the teams behind Zustand, Jotai, Redux Toolkit, Recoil, and many others. Each of these libraries is powerful, well-maintained, and trusted by thousands of developers—including myself at different stages of my career.

But after building useS, testing it extensively, and embracing its simplicity and flexibility, I can confidently say that this is how I want to manage state in React moving forward. Whether it's a local counter or a shared global structure, I now reach for useS without hesitation.

You don’t have to agree with the ranking—but I hope it helps you discover new tools and revisit how you manage state in your own projects.


What’s Next for useS?

The journey of useS is just getting started. Right now, I’m actively working on adding built-in persistence support for both web and mobile environments. The goal is to cover all the reasonable state management use cases without sacrificing the simplicity that defines this library.

Most of the core use cases are already tested and in production. I'm constantly looking for new patterns and edge cases to make sure future features are reliable and backwards compatible.

Looking ahead, I’d also love to improve the developer experience with better debugging tools—possibly a browser extension or even a lightweight VS Code plugin. There’s so much potential to make useS even more powerful without losing its minimal API.

How to Contribute

If this sounds like a journey you'd like to be part of, I welcome contributions, ideas, and feedback from the community:

Try it Yourself

Whether you're building a simple counter or a complex multi-screen app, give useS a try. You might find that managing state in React doesn’t have to be complicated after all.

Top comments (0)