Primitive and flexible state management for React


Version requirement

Jotai uses TypeScript 3.8+ syntax. Upgrade your TypeScript version if you're on 3.7.5 or lower.

Jotai relies heavily on type inferences and requires strictNullChecks to be enabled. Consider adding "strict": true in your tsconfig.json. #550 #802 #838


Primitive atoms are basically type inferred

const numAtom = atom(0) // primitive number atom
const strAtom = atom('') // primitive string atom

Primitive atoms can be explicitly typed

const numAtom = atom<number>(0)
const numAtom = atom<number | null>(0)
const arrAtom = atom<string[]>([])

Derived atoms are also type inferred and explicitly typed

const asyncStrAtom = atom(async () => 'foo')
const writeOnlyAtom = atom(null, (_get, set, str: string) => set(fooAtom, str))
const readWriteAtom = atom<string, number>(
(get) => get(strAtom),
(_get, set, num) => set(strAtom, String(num))

useAtom is typed based on atom types

const [num, setNum] = useAtom(primitiveNumAtom)
const [num] = useAtom(readOnlyNumAtom)
const [, setNum] = useAtom(writeOnlyNumAtom)

Access to the value type of an atom

import { ExtractAtomValue, useAtomValue } from 'jotai'
import { userAtom } from 'state'
import { useQuery } from '@tanstack/react-query'
export default function WriteReview(hid) {
const user = useAtomValue(userAtom)
const res = useGetReviewQuery(user)
function useGetReviewQuery(user: ExtractAtomValue<typeof userAtom>) {
return fetch('/api/user/' + + '/review')