use-s-react
What is useS?
Is a minimal yet powerful React hook for managing both local and global state — with zero boilerplate.
- 🧠 Feels like
useState
, so it's instantly familiar. - 🚫 No Providers. No Context. No extra setup.
- ⚡ Scales globally without wrappers or nested trees.
- 🧩 Works with any state shape: primitives, arrays, objects, deeply nested structures.
- 🔁 Supports
setState(prev => ...)
logic. - 🧼 Built with TypeScript and powered by
useSyncExternalStore
andfull-copy
for deep reactivity.
It's a native and lightweight alternative to Zustand, Redux Toolkit, React Context, React useReducer and even useState
itself — perfect for projects that need power and simplicity without the overhead.
📦 Installation
Install via npm or your preferred package manager:
npm i use-s-react
🚀 Quick Start
🔸 Import the hook
import { useS } from "use-s-react";
🔸 Local state (same as useState
)
const [count, setCount] = useS(0);
🔸 Global state (via config object)
const [count, setCount] = useS({ value: 0, key: 'global-counter' });
✅ Best Practice: External Global Store
Use a store.ts
to centralize your global state configs:
// store.ts
export const store = {
globalCounter: {
value: 0,
key: 'global-counter',
},
globalUser: {
value: {
name: "John",
age: 30,
},
key: 'global-user',
}
};
// Then import and use it:
import { store } from "./store";
const [count, setCount] = useS(store.globalCounter);
♻️ Sharing Global State Between Components
🔸 ComponentA.tsx
import { useS } from "use-s-react";
export function ComponentA() {
const [count, setCount] = useS({ value: 0, key: 'global-counter' });
return (
<div>
<h3>Component A</h3>
<p>Count: {count}</p>
<button onClick={() => setCount(prev => prev + 1)}>Increment</button>
</div>
);
}
🔸 ComponentB.tsx
import { useS } from "use-s-react";
export function ComponentB() {
const [count] = useS({ value: 0, key: 'global-counter' });
return (
<div>
<h3>Component B</h3>
<p>Count from A: {count}</p>
</div>
);
}
🔁 Deep Updates & More
- Updates are deep-merged using
full-copy
, preserving nested structures:
setUser({ info: { lang: "es" } }); // doesn't erase other info keys
- You can also return a new state based on the previous:
setUser(prev => ({
info: {
lang: prev === 'en' ? 'es',
},
})
);
- Destructuring deeply
const [{ name, age }, setUser] = useS({
value: {
name: "John",
age: 20
},
key: "global-user"
});
- Infer state typing based on initial value
🧪 Debugging (Optional)
Use debugGlobalStore()
to inspect all global state in the console:
import { debugGlobalStore } from "use-s-react";
useEffect(() => {
debugGlobalStore(); // logs all keys
debugGlobalStore({ filterKey: "global-user" }); // only "global-user"
debugGlobalStore({ withConsoleTable: false }); // plain logs
}, []);
✅ Fully compatible with React Native — debugGlobalStore() gracefully falls back to console.log when console.table is not available.
🔍 console.table will be used when possible for better clarity.
🔧 API Summary
useS(initialValue: T)
Creates a local state, just like useState (but with super powers).
useS({ value, key })
Makes the state globally available for use by other components. The key must be unique.
📜 License
MIT © ChristBM