Lightweight React state management for shared UI state.
Nucleus State is a small TypeScript-first state library for React. It is designed for state that needs to be shared across components without adding providers, reducers, or heavy store setup.
It works well for:
- modals and drawers
- tabs and view state
- theme and preference state
- form steps and temporary UI data
- small derived values built from existing atoms
npm install @sinhaparth5/nucleus-stateimport { createAtom, useAtom } from '@sinhaparth5/nucleus-state';
const modalAtom = createAtom(false, { name: 'modal' });
function OpenButton() {
const [, setModalOpen] = useAtom(modalAtom);
return <button onClick={() => setModalOpen(true)}>Open modal</button>;
}
function Modal() {
const [isOpen, setModalOpen] = useAtom(modalAtom);
if (!isOpen) {
return null;
}
return (
<div>
<p>Settings</p>
<button onClick={() => setModalOpen(false)}>Close</button>
</div>
);
}- Provider-free API
- Small surface area
- TypeScript-first ergonomics
- Read/write hooks that feel like React state
- Built-in persistence helpers
- Derived state with computed atoms
- Development-time atom registry for debugging
Creates a mutable atom with get(), set(), reset(), and subscribe().
const countAtom = createAtom(0);
const themeAtom = createAtom('light', { persist: 'theme' });Options:
name: debug label for development toolingpersist: storage key used for persistencestorage: custom storage object withgetItemandsetItem
Returns the current value and setter.
const [count, setCount] = useAtom(countAtom);
setCount(1);
setCount(prev => prev + 1);Returns the current value only.
const theme = useAtomValue(themeAtom);Returns the setter only.
const setTheme = useSetAtom(themeAtom);Restores an atom to its original initial value.
const countAtom = createAtom(0);
countAtom.set(5);
countAtom.reset();
countAtom.get(); // 0Creates a read-only derived atom that updates from other atoms.
import {
createAtom,
createComputed,
useAtomValue,
} from '@sinhaparth5/nucleus-state';
const firstNameAtom = createAtom('Parth');
const lastNameAtom = createAtom('Sinha');
const fullNameAtom = createComputed(
[firstNameAtom, lastNameAtom],
() => `${firstNameAtom.get()} ${lastNameAtom.get()}`,
);
function ProfileName() {
const fullName = useAtomValue(fullNameAtom);
return <h1>{fullName}</h1>;
}You can also use the simple form:
const timestampAtom = createComputed(() => Date.now());That form computes once and does not subscribe to dependencies automatically.
Atoms can persist state in browser storage and safely fall back when storage is unavailable.
const settingsAtom = createAtom(
{ notifications: true, language: 'en' },
{ persist: 'user-settings' },
);For convenience, the package also exports:
import {
createPersistedAtom,
createSessionAtom,
} from '@sinhaparth5/nucleus-state';
const themeAtom = createPersistedAtom('light', 'theme');
const wizardAtom = createSessionAtom({ step: 1 }, 'wizard');Custom storage is supported:
const draftAtom = createAtom(
{ value: '' },
{
persist: 'draft',
storage: {
getItem: key => sessionStorage.getItem(key),
setItem: (key, value) => sessionStorage.setItem(key, value),
},
},
);In development, named atoms are exposed on window.__NUCLEUS_ATOMS__.
const userAtom = createAtom(null, { name: 'currentUser' });
console.log(window.__NUCLEUS_ATOMS__?.list());
console.log(window.__NUCLEUS_ATOMS__?.get('currentUser'));The package is designed for strong type inference out of the box.
interface User {
id: number;
name: string;
}
const userAtom = createAtom<User | null>(null);
const [user, setUser] = useAtom(userAtom);
const userName = useAtomValue(userAtom)?.name;Example source lives in:
examples/basic-usage/App.tsxexamples/modal-management/App.tsxexamples/form-wizard/App.tsx
A runnable playground is available in examples/playground.
pnpm example:devUse this post if you want to share the project:
Built `nucleus-state` for lightweight shared React state without providers or store boilerplate.
- TypeScript-first
- atom-based API
- computed state
- persistence helpers
Repo: https://github.com/sinhaparth5/nucleus-state
#react #typescript #opensource #webdev
- React
^19.1.0 - TypeScript
4.1+
BSD-2-Clause © Parth Sinha