React LogoJotai

Jotai (pronounced "yo-tie," meaning "atom" in Japanese) is a primitive and flexible state management library for React. It aims to provide a minimal API for managing shared, global, or component-level state with a focus on developer experience and performance.

At its core, Jotai revolves around the concept of "atoms." An atom is a small, independent piece of state. Components can "subscribe" to these atoms, and only re-render when the specific atom they depend on changes. This makes Jotai highly performant and efficient, as it avoids unnecessary re-renders.

Key features and concepts of Jotai include:

* Atoms: The fundamental building blocks. You define an atom using the `atom()` function, providing an initial value. For example, `const countAtom = atom(0);`.
* `useAtom` Hook: This is the primary hook for interacting with atoms in your React components. It returns a tuple `[value, setValue]`, similar to React's `useState`, allowing you to read the current state of an atom and update it.
* Derived Atoms: Jotai allows you to create atoms whose values are derived from other atoms. These can be read-only (e.g., a computed value like a sum of other atoms) or writeable (allowing updates to affect underlying atoms). This provides powerful composition capabilities.
* Asynchronous Atoms: You can define atoms that resolve their values asynchronously, making it easy to handle data fetching or other async operations.
* Performance: Jotai is highly optimized. It tracks dependencies precisely, ensuring that only components that are actually using a changed atom are re-rendered.
* TypeScript Support: Jotai offers excellent type inference and strong typing, making it a great choice for TypeScript projects.
* Minimal Bundle Size: The library itself is very small, contributing minimally to your application's bundle size.
* Provider (Optional but Recommended): For a full application, you typically wrap your component tree with an `<Provider>` component. This provides the context for Jotai atoms to function globally, though it's also possible to use atoms without a global Provider for local component state.
* Simplicity and Flexibility: Jotai's API is intentionally simple, yet it's powerful enough to handle complex state management scenarios, from simple counters to intricate application logic. It's often compared to Recoil due to its atom-based approach but aims for an even smaller and more primitive API.

Jotai is an excellent choice for React developers looking for a modern, performant, and easy-to-use state management solution that scales from small to large applications.

Example Code

import React from 'react';
import { atom, useAtom, Provider } from 'jotai';

// 1. Define a base atom
const countAtom = atom(0);

// 2. Define a derived read-only atom
const doubleCountAtom = atom((get) => get(countAtom) * 2);

// 3. Define a derived read-write atom (optional, but demonstrates more complex logic)
const incrementByAtom = atom(
  (get) => get(countAtom), // Read function
  (get, set, incrementBy: number) => { // Write function
    set(countAtom, (c) => c + incrementBy);
  }
);

function CounterDisplay() {
  const [count] = useAtom(countAtom);
  const [doubleCount] = useAtom(doubleCountAtom);

  return (
    <div style={{ border: '1px solid #ccc', padding: '10px', margin: '10px' }}>
      <h3>Counter Display</h3>
      <p>Current Count: {count}</p>
      <p>Double Count: {doubleCount}</p>
    </div>
  );
}

function CounterControls() {
  const [count, setCount] = useAtom(countAtom);
  const [, incrementCountBy] = useAtom(incrementByAtom); // Using the write function of a derived atom

  return (
    <div style={{ border: '1px solid #ccc', padding: '10px', margin: '10px' }}>
      <h3>Counter Controls</h3>
      <p>Current Count (local check): {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>Increment</button>
      <button onClick={() => setCount((c) => c - 1)}>Decrement</button>
      <button onClick={() => incrementCountBy(5)}>Increment by 5 (via derived atom)</button>
    </div>
  );
}

function App() {
  return (
    // The Provider is necessary to make atoms accessible throughout your app
    // for multiple components to share state.
    <Provider>
      <h1>Jotai Example</h1>
      <CounterDisplay />
      <CounterControls />
      <p>
        Both components above share and update the same <code>countAtom</code> state,
        demonstrating global state management with Jotai.
      </p>
    </Provider>
  );
}

export default App;