jotai-x
jotai-x auto-generates type-safe hooks, providers, and scoped state stores on top of Jotai.
Repository Health
Technical Analysis
jotai-x is a thin factory layer over Jotai that turns a plain state object into a fully-typed set of hooks, setters, and a scoped React provider. Instead of manually wiring individual atoms with useAtom, useAtomValue, and useSetAtom for every field, its single createAtomStore function takes an initial state object and an options object and returns a bundle of use<Name>Value, use<Name>Set, and use<Name>State hooks, a <Name>Provider component, and a raw atom record — all inferred from the shape of the input state.
The library supports SSR-friendly hydration, prop-driven state synchronization, scoped/nested providers for running multiple instances of the same store, and an extend option for adding computed/derived atoms alongside the base fields. It has a sister package, zustand-x, offering the same generated-hook API shape over Zustand for teams that prefer a global-store model instead of React Context-based scoping.
What You Get
- Auto-generated typed hooks -
use<Name>Value,use<Name>Set, anduse<Name>Statehooks are generated per state field, all with inferred TypeScript types. - Scoped React providers - A
<Name>Providercomponent that hydrates initial values, syncs prop changes, and supports nested/scoped store instances via ascopeprop. - Derived/computed atoms via extend - The
extendoption lets you add Jotai-computed atoms on top of the base store fields, accessible through the same hook API. - Store instance API -
use<Name>Store()returns a single object exposingget,set,useValue,useState, andsubscribemethods for every field, plus raw-atom variants (getAtom,setAtom, etc.) for interop with existing Jotai atoms. - SSR hydration support - Built-in
useHydrateStore/useSyncStoreutilities handle server-rendered initial values without extra setup.
Common Use Cases
- Replacing verbose Jotai boilerplate - Teams that already use Jotai but are tired of manually declaring
useAtom/useAtomValuecalls for every state field adopt jotai-x to get typed hooks for free. - Per-component or per-feature scoped state - Using
<Name>Provider scope="...">to run multiple independent instances of the same store (e.g. one per modal, tab, or list item) without global singletons. - SSR/Next.js apps needing hydration - Passing
initialValuesinto a Provider to hydrate atoms from server-fetched data on first render. - Migrating from Zustand-style stores - Projects that like the store-object API of
zustand-xbut want Jotai’s atom model underneath.
Under The Hood
Architecture
The core lives in a single ~860-line createAtomStore.ts that builds a store using a prototype-based factory (UseStoreApiFactory), populating getter/setter/subscribe methods onto its prototype in a loop for performance rather than constructing a fresh object shape per hook call. createAtomProvider.tsx supplies a React Context (AtomStoreContext, a Map keyed by "storeName:scope") holding vanilla Jotai stores, with a HydrateAtoms component handling SSR hydration and prop-sync through a dedicated write-only Jotai atom. useHydrateStore.ts contains the hydrate/sync mechanics built on jotai/utils’ useHydrateAtoms plus a manual diff-and-set effect, and atomWithFn.ts is a narrow, well-isolated utility working around Jotai’s inability to store function values in atoms by wrapping/unwrapping them in a marker object. The pieces are small and independently testable even though the central factory function is dense with generic type machinery.
Tech Stack
Written in strict-mode TypeScript with React (>=17) and Jotai (>=2.0.0) as peer dependencies. The repo is a Yarn Berry + Turborepo monorepo (turbo.json defines build/lint/test/typecheck pipelines), building the package with tsup for dual ESM/CJS output, linting through a shared multi-base ESLint config (turbo, typescript, react, react-compiler, unicorn, prettier presets), and auto-generating the index.ts barrel export with barrelsby. Releases are versioned and published via Changesets.
Code Quality
Two Vitest spec files (createAtomStore.spec.tsx at 1,543 lines and elementAtom.spec.tsx at 220 lines) exercise hooks, providers, selectors, scoping, and hydration behavior against jsdom with Testing Library, giving the ~990-line source a generous test surface. Strict TypeScript and a dedicated CI workflow (ci-packages.yml) lint and test every push/PR touching packages/**. Failure paths favor explicit console warnings (e.g. useAtomStore warns when a store isn’t found) over silent swallowing.
What Makes It Unique
jotai-x’s core idea is deriving a complete hook surface purely from the shape of a plain state object — passing { name, count } to createAtomStore yields fully-typed useAppValue, useAppSet, and useAppState hooks per field without a single hand-written atom() call. The generated Provider’s scope and resetKey props give per-instance store isolation without separate Context definitions per store, and extend layers computed atoms onto the same generated API. The approach is a genuine ergonomic improvement over hand-rolled Jotai wiring, though the codegen-from-config-object pattern has precedent in the author’s own sibling package, zustand-x.