emotion

Feedback Loops

The psychological need for confirmation after actions — when a system does not acknowledge what the user did, anxiety fills the gap.

Plain English

Every action a user takes is a small act of trust. They pressed a button. Did it work? The moment between action and confirmation is psychologically loaded — the longer and more ambiguous it is, the more anxiety builds. Feedback loops close that gap. A spinner says 'I heard you, I am working'. A success animation says 'it worked'. A subtle button colour change says 'yes, you pressed that'. The interesting design challenge is calibrating the feedback to the action size: a form submission needs more ceremony than a checkbox tick. Too little feedback creates doubt. Too much feedback is condescending and slow.

Research background

Three feedback timing tiers: (1) Immediate (< 100ms) — visual state change on press (colour, scale, border); no async required. (2) In-progress (100ms–indefinite) — spinner, progress bar, or skeleton; start at 200ms delay to avoid flash on fast responses. (3) Completion — success state at 200–400ms, auto-dismiss toasts at 3–4 s. For async actions: use optimistic UI where safe (toggle, like, bookmark) — apply the success state immediately, revert on error. For destructive actions: use 'undo' pattern rather than confirmation dialogs (shows the action, provides escape, doesn't interrupt flow). Always pair visual feedback with ARIA live regions for screen readers: aria-live='polite' for success, aria-live='assertive' for errors.

UI examples

✓ Applying the principle

Slack's message send — the message appears instantly in the thread (optimistic UI), a small clock icon shows it is pending, a checkmark appears when delivered. Three feedback states without a single blocking moment.

✗ Violating it

A form submit button that does nothing visually for 2 seconds while the API call runs — users click again, causing double submissions, then question whether the site is broken.

AI Prompt

Paste into Claude, Cursor, Bolt, or v0.

Implement a three-tier feedback loop for this form submission: (1) Immediate — button goes to loading state (spinner + disabled) on click. (2) In-progress — after 300ms show a progress indicator if still loading. (3) Completion — on success, show an inline success message with a checkmark animation (200ms fade-in scale-in); on error, shake the form and show an inline error message. Add aria-live="polite" to the status region.