nucleus-state
v1.0.4
Published
Lightweight React state management for UI components
Maintainers
Readme
Nucleus State
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
Installation
npm install @sinhaparth5/nucleus-stateQuick Start
import { 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>
);
}Why Nucleus State
- 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
API
createAtom(initialValue, options?)
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
useAtom(atom)
Returns the current value and setter.
const [count, setCount] = useAtom(countAtom);
setCount(1);
setCount(prev => prev + 1);useAtomValue(atom)
Returns the current value only.
const theme = useAtomValue(themeAtom);useSetAtom(atom)
Returns the setter only.
const setTheme = useSetAtom(themeAtom);atom.reset()
Restores an atom to its original initial value.
const countAtom = createAtom(0);
countAtom.set(5);
countAtom.reset();
countAtom.get(); // 0createComputed(dependencies, compute)
Creates 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.
Persistence
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),
},
},
);Devtools
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'));TypeScript
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;Examples
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:devRequirements
- React
^19.1.0 - TypeScript
4.1+
License
BSD-2-Clause © Parth Sinha
