Documentation Index Fetch the complete documentation index at: https://mintlify.com/reatom/reatom/llms.txt
Use this file to discover all available pages before exploring further.
Quick Start
This guide will walk you through building a simple counter application with Reatom and React. You’ll learn the core concepts while creating a working example.
Prerequisites
Make sure you have Reatom installed:
npm install @reatom/core @reatom/react
See the Installation guide for other package managers.
Building a Counter
Let’s build a counter app step by step to understand Reatom’s core primitives.
Create an atom for the counter state
An atom is the base state container in Reatom. It holds a single value that can be read and updated. import { atom } from '@reatom/core'
const counter = atom ( 0 )
You can read and update atoms directly: // Read the atom state
console . log ( counter ()) // 0
// Write a new state to the atom
counter . set ( 1 )
console . log ( counter ()) // 1
// Update using a function
counter . set (( state ) => state + 5 )
console . log ( counter ()) // 6
Create a computed value
A computed creates lazy memoized computations that automatically update when dependencies change. import { atom , computed } from '@reatom/core'
const counter = atom ( 0 )
const isEven = computed (() => counter () % 2 === 0 )
console . log ( isEven ()) // true
counter . set ( 1 )
console . log ( isEven ()) // false
Computed values are lazy - they only recalculate when accessed and their dependencies have changed.
Create the Counter component
Use reatomComponent to create a reactive React component that automatically subscribes to atoms. import { atom , computed } from '@reatom/core'
import { reatomComponent } from '@reatom/react'
const counter = atom ( 0 )
const isEven = computed (() => counter () % 2 === 0 )
const Counter = reatomComponent (() => (
< section >
< p >
{ counter () } is { isEven () ? 'even' : 'odd' }
</ p >
< button onClick = { () => counter . set ( v => v + 1 ) } > Increment </ button >
</ section >
))
export default Counter
The coolest thing about reatomComponent is that you can use reactive states (atoms) in any order without the rules of hooks!
Add the component to your app
Import and use your Counter component like any other React component: import Counter from './Counter'
function App () {
return (
< div className = "App" >
< h1 > My Counter App </ h1 >
< Counter />
</ div >
)
}
export default App
Complete Example
Here’s the full counter example with all the code together:
import { atom , computed } from '@reatom/core'
import { reatomComponent } from '@reatom/react'
const counter = atom ( 0 )
const isEven = computed (() => counter () % 2 === 0 )
const Counter = reatomComponent (() => (
< section >
< p >
{ counter () } is { isEven () ? 'even' : 'odd' }
</ p >
< button onClick = { () => counter . set ( v => v + 1 ) } > Increment </ button >
</ section >
))
export default Counter
Understanding Effects
Effects let you react to state changes immediately. They’re similar to computed but run automatically after creation.
import { atom , computed , effect } from '@reatom/core'
const counter = atom ( 0 )
const isEven = computed (() => counter () % 2 === 0 )
effect (() => {
console . log ( ` ${ counter () } is ${ isEven () ? 'even' : 'odd' } ` )
})
// This will log: "0 is even"
counter . set ( 1 )
// This will log: "1 is odd"
Effects are perfect for running long-lived processes like API polling or timers that work independently of the UI.
Organizing with Actions
As your app grows, you can organize complex operations using actions with the extend method:
import { atom } from '@reatom/core'
export const list = atom ([], 'list' ). extend (( target ) => ({
isLoading: atom ( false , ` ${ target . name } .isLoading` ),
async load ( page : number ) {
target . isLoading . set ( true )
const response = await fetch ( `/api/list?page= ${ page } ` )
const payload = await response . json ()
target . set ( payload )
target . isLoading . set ( false )
},
}))
list . load ( 1 )
console . log ( list . isLoading ())
Real-World Example: Search with Async Data
Here’s a more complex example from the Reatom source code showing async data handling:
import { atom , computed , withAsyncData , sleep , wrap } from '@reatom/core'
import { searchIssues } from './api'
export const issueQuery = atom ( '' , 'issueQuery' )
export const issuePage = atom ( 0 , 'issuePage' )
export const issuePerPage = atom ( 10 , 'issuePerPage' )
export const issuesResource = computed ( async () => {
const query = issueQuery ()
if ( ! query ) {
return {
items: [],
total_count: 0 ,
incomplete_results: false ,
}
}
// Debounce the search
await wrap ( sleep ( 250 ))
const filters = {
query ,
page: issuePage (),
perPage: issuePerPage (),
}
return searchIssues ( filters )
}, 'issuesResource' ). extend ( withAsyncData ())
export const isIssuesLoading = computed (
() => ! issuesResource . ready (),
'isIssuesLoading' ,
)
export const issuesError = issuesResource . error
The withAsyncData extension adds helpful properties like ready(), data(), and error() to track async operations.
Next Steps
Now that you’ve built your first Reatom application, explore these topics:
Core Concepts: Atoms Deep dive into atoms and state management
Core Concepts: Computed Master lazy memoized computations
Core Concepts: Effects Learn about reactive side effects
Async Operations Handle async data and API calls
Try the Template
Want to see a full-featured example? Check out the official React template with search, filtering, and pagination: