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-update
Example

The 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.
Process

How it works

Three simple steps happen automatically every time you update state with a mutation function.

01

Update instantly

The UI changes immediately when the user interacts. No loading spinners, no waiting. Your app feels fast because it is fast.

02

Save in background

The API request runs in the background while the user continues working. Non-blocking, non-intrusive, exactly how it should be.

03

Auto rollback

If the request fails, the state automatically reverts to what it was before. No manual error handling, no cleanup code required.

Real examples

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' 
    })
  )
}
Features

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.

Comparison

Before and after

Without optimistic updates
const handleClick = async () => {
  setLoading(true)
  try {
    await fetch('/api/endpoint')
    await refetch()
  } catch (err) {
    setError(err)
  }
  setLoading(false)
}

// Users wait 500ms+ for every action
With optimistic updates
const [data, setData] = useOptimistic(initial)

const handleClick = () => {
  setData(
    newData,
    () => fetch('/api/endpoint')
  )
}

// Instant feedback, automatic rollback