---
title: Async
description: This doc describes about the behavior with async.
nav: 1.03
---
Using async atoms, you gain access to real-world data while still managing them directly from your atoms and with incredible ease.
We can separate them in two main categories:
- Async read atoms: async request is started instantly as soon as you try to get its value. You could relate to them as "smart getters".
- Async write atoms: async request is started at a specific moment. You could relate to them as "actions".
## Async read atom
The `read` function of an atom can return a promise.
```js
const countAtom = atom(1)
const asyncAtom = atom(async (get) => get(countAtom) * 2)
```
Jotai is inherently leveraging `Suspense` to handle asynchronous flows.
```jsx
const ComponentUsingAsyncAtoms = () => {
const [num] = useAtom(asyncAtom)
// here `num` is always `number` even though asyncAtom returns a Promise
}
const App = () => {
return (
)
}
```
Alternatively, you could avoid the inherent suspending that Jotai does for you, by wrapping your atoms with the [`loadable` API](../utils/loadable.mdx).
If another atom uses an async atom, it will return a promise. So, we need to make the atom also async.
```js
const anotherAtom = atom(async (get) => (await get(asyncAtom)) / 2)
```
This also applies to an atom with write function.
```js
const asyncAtom = atom(async (get) => ...)
const writeAtom = atom(null, async (get, set, payload) => {
await get(asyncAtom)
// ...
})
```
## Async write atom
Async write atoms are another kind of async atom. When the `write` function of atom returns a promise.
```js
const countAtom = atom(1)
const asyncIncrementAtom = atom(null, async (get, set) => {
// await something
set(countAtom, get(countAtom) + 1)
})
const Component = () => {
const [, increment] = useAtom(asyncIncrementAtom)
const handleClick = () => {
increment()
}
// ...
}
```
## Async sometimes
An interesting pattern that can be achieved with Jotai is switching from async to sync to trigger suspending when wanted.
```js
const request = async () => fetch('https://...').then((res) => res.json())
const baseAtom = atom(0)
const Component = () => {
const [value, setValue] = useAtom(baseAtom)
const handleClick = () => {
setValue(request()) // Will suspend until request resolves
}
// ...
}
```
### Usage in TypeScript
In TypeScript `atom(0)` is inferred as `PrimitiveAtom`. It cannot accept `Promise` as a value so preceding code would not typecheck. To accomodate for that you need to type your atom explicitly and add `Promise` as accepted value.
```ts
const baseAtom = atom>(0) // Will accept sync and async values
```
## Async forever
Sometimes you may want to suspend until an unpredetermined moment (or never).
```js
const baseAtom = atom(new Promise(() => {})) // Will be suspend until set otherwise
```
## Suspense
Async support is first class in Jotai. It fully leverages React Suspense at its core.
> Technically, Suspense usage other than React.lazy is still unsupported / undocumented in React 17. If this is blocking, so you can still use the [`loadable` API](../utils/loadable.mdx) to avoid suspending
To use async atoms, you need to wrap your component tree with ``.
> If you have a ``, place **at least one** `` inside said ``; otherwise, it may cause an endless loop while rendering the components.
```jsx
const App = () => (
)
```
Having more ``s in the component tree is also possible and must be considered to profit from Jotai inherent handling at best.