interactionintermediate

Optimistic UI

Immediately updating the UI to show the expected success state before the server confirms the action, then rolling back if the request fails.

Plain English

When you like a tweet, the heart turns red instantly — it does not wait 200ms for Twitter's server to confirm. That is optimistic UI. The interface "assumes" the operation will succeed and updates immediately, creating an experience that feels instant and responsive. If the server returns an error, the UI quietly rolls back to the previous state and shows an error message. This pattern works best for actions that almost always succeed: likes, saves, reorders, form submissions with good client-side validation. The opposite approach — waiting for server confirmation before updating — is called pessimistic UI, and it makes every action feel sluggish, even on fast connections.

Technical

Implementation pattern: (1) Capture the current state as a rollback snapshot. (2) Immediately apply the optimistic state update to local state (useState/Zustand/Redux). (3) Fire the async API call in the background. (4) On success, optionally reconcile with the real server response (e.g., replace temp ID with real DB ID). (5) On failure, restore the rollback snapshot and surface an error. In React: `const prev = items; setItems(optimistic); try { await api.update(); } catch { setItems(prev); showError(); }`. React Query and SWR both have built-in `onMutate`/`onError` hooks for this pattern. For list reorders (drag-and-drop), update the array immediately and persist in the background. Key constraint: only use optimistic UI for low-stakes, reversible, idempotent-ish actions — never for payment processing or destructive deletes without explicit confirmation.

Live Demo

Optimistic UI

The UI updates immediately on click (optimistic). After 1.5s, the server responds — 80% success, 20% rollback with a shake animation.

Click to like

What's happening

1

Optimistic update

UI updates immediately — no wait

2

Server request in flight

User doesn't wait for this

3

Server response

Confirm or rollback

Ready

Optimistic UI trades perfect accuracy for perceived speed — rollback handles the rare failure.

Usage

✓ Good usage

A bookmark button that flips to "Saved" instantly on click, persists in the background via API, and reverts to "Save" with a brief "Failed to save" toast if the network request fails.

✗ Bad usage

Applying optimistic UI to a "Delete Account" action — immediately hiding the account page before server confirmation means there is no graceful rollback path if the deletion fails or is rejected.

Common mistakes

AI Prompt Example

Copy this into Claude, Cursor, Bolt, or v0.

Implement optimistic UI on the Like button. On click: immediately toggle `liked` boolean and increment/decrement `likeCount` in local state. Save a `previousState` snapshot first. Fire `PATCH /api/posts/:id/like` in the background. On error: restore `previousState` and show a toast "Could not update — please try again." On success: optionally sync the server-returned count to catch discrepancies.