jotai-x

jotai-x auto-generates type-safe hooks, providers, and scoped state stores on top of Jotai.

Library
npm
v2.3.4
33stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
32/100Needs Attention
Development Activity8
Maintenance32
Community20
Maturity48
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture74
Code Quality82
Innovation72
Learning Curve55

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, and use<Name>State hooks are generated per state field, all with inferred TypeScript types.
  • Scoped React providers - A <Name>Provider component that hydrates initial values, syncs prop changes, and supports nested/scoped store instances via a scope prop.
  • Derived/computed atoms via extend - The extend option 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 exposing get, set, useValue, useState, and subscribe methods for every field, plus raw-atom variants (getAtom, setAtom, etc.) for interop with existing Jotai atoms.
  • SSR hydration support - Built-in useHydrateStore/useSyncStore utilities 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/useAtomValue calls 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 initialValues into 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-x but 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/utilsuseHydrateAtoms 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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search