Instant UI updates
Make your React apps feel instant with optimistic updates. Update the UI immediately, save in the background, and automatically rollback on errors.
One hook that works like useState. Zero configuration. Zero dependencies.
npm install @chemmangat/optimistic-updateThe simplest use case
Works exactly like useState, but with an optional second parameter for your API call. If the request fails, the UI automatically reverts to its previous state.
import { useOptimistic } from '@chemmangat/optimistic-update'
function Counter() {
const [count, setCount] = useOptimistic(0)
return (
<button onClick={() =>
setCount(count + 1, () => fetch('/api/increment', { method: 'POST' }))
}>
{count}
</button>
)
}
// That's it. The UI updates instantly. If the fetch fails, it rolls back automatically.How it works
Three simple steps happen automatically every time you update state with a mutation function.
Update instantly
The UI changes immediately when the user interacts. No loading spinners, no waiting. Your app feels fast because it is fast.
Save in background
The API request runs in the background while the user continues working. Non-blocking, non-intrusive, exactly how it should be.
Auto rollback
If the request fails, the state automatically reverts to what it was before. No manual error handling, no cleanup code required.
Common use cases
From like buttons to todo lists, optimistic updates make every interaction feel instant.
Like button
const [likes, setLikes] = useOptimistic(42)
<button onClick={() =>
setLikes(likes + 1,
() => fetch('/api/like', { method: 'POST' })
)
}>
{likes} likes
</button>Delete todo
const [todos, setTodos] = useOptimistic(items)
const remove = (id) => {
setTodos(
todos.filter(t => t.id !== id),
() => fetch(`/api/todos/${id}`, {
method: 'DELETE'
})
)
}Why developers choose this
Built for developers who want great UX without the complexity.
Zero setup required
No providers to wrap your app in. No configuration files to manage. Just import the hook and start using it. Works with any React project.
Familiar API
If you know how to use useState, you already know how to use this. Same signature, same patterns. Zero learning curve.
Automatic error handling
Failed requests automatically trigger a rollback to the previous state. No try-catch blocks, no manual state restoration, no cleanup code.
Lightweight bundle
Only 20KB minified. Zero dependencies except React. Fast to download, fast to parse, fast to execute.
Before and after
const handleClick = async () => {
setLoading(true)
try {
await fetch('/api/endpoint')
await refetch()
} catch (err) {
setError(err)
}
setLoading(false)
}
// Users wait 500ms+ for every actionconst [data, setData] = useOptimistic(initial)
const handleClick = () => {
setData(
newData,
() => fetch('/api/endpoint')
)
}
// Instant feedback, automatic rollback