Quantum

quantum-state

Atomic, Observable State for Server-First Apps.

State management is too complex. quantum-state is a 2kb, zero-dependency state machine for Next.js 14. It is built from the ground up for React Server Components (RSC) and the use-sync-external-store hook. No boilerplate. No providers. Just state.

The Philosophy

Other libraries were built for a client-only world. quantum-state is server-first.

Atomic & Zero-Boilerplate

No reducers, no actions, no dispatchers. Define a single 'quantum' of state (an atom) and use it anywhere in your app. Your components subscribe directly to only the state they need.

"Quantum" Microtask Batching

Why 2kb? It's all in the scheduler. quantum-state automatically batches all state updates within a single event loop tick. This provides extreme performance for high-frequency updates (e.g., IoT data streams, financial tickers, or wireless channel simulations) with zero re-render tearing.

Server-First Native (RSC)

This is not an old library with a new wrapper. It's built for the App Router. You can safely pass state from Server Components to Client Components. It's free of 'context provider hell.' You don't even need a <Provider>.

Installation

Add it to your project.

npm install quantum-state

5-Minute "Hello World"

This is all you need.

Step 1: Define an atom

An atom is the smallest possible unit of state. Create one in a central file.

// /lib/atoms.js
import { atom } from 'quantum-state';

// This is your global, observable state.
export const modelStatusAtom = atom('Idle');

// Atoms can hold any value, including objects.
export const csiDataAtom = atom({
  timestamp: null,
  values: [],
});

/lib/atoms.js

Step 2: Read & Write to the atom

Use the useAtom hook in any Client Component to get the value and a setter function. It works just like useState.

// /components/RunSimulationButton.jsx
'use client';

import { useAtom } from 'quantum-state';
import { modelStatusAtom } from '@/lib/atoms';

export function RunSimulationButton() {
  const [status, setStatus] = useAtom(modelStatusAtom);

  const handleClick = async () => {
    setStatus('Running...');
    // await runSim();
    setStatus('Idle');
  };

  return (
    <button onClick={handleClick} disabled={status === 'Running...'}>
      {status === 'Running...' ? 'Simulating...' : 'Run Simulation'}
    </button>
  );
}

/components/RunSimulationButton.jsx

Step 3: Read only

If a component only needs to read the state, use the useAtomValue hook. This is cheaper and prevents re-renders if the component doesn't write.

// /components/StatusDisplay.jsx
'use client';

import { useAtomValue } from 'quantum-state';
import { modelStatusAtom } from '@/lib/atoms';

export function StatusDisplay() {
  const status = useAtomValue(modelStatusAtom);

  return (
    <div>
      <strong>Model Status:</strong> {status}
    </div>
  );
}

/components/StatusDisplay.jsx

You're Done.

Seriously. That's it.

You now have global state. StatusDisplay and RunSimulationButton are fully in sync. You did not wrap your app in a <Provider>. You did not write a reducer.

It just works.

Next Steps

Read the Core API guide.

See the Advanced Recipes for high-frequency updates.

Check out the DevTools guide.

Ready to eliminate state complexity?

Join thousands of developers shipping faster with quantum-state.