Skip to content

Progress Durability ​

Progress durability protects work the user has already done but has not submitted yet.

This is private, local progress. It should survive refreshes and browser restarts, but it is not a database record and it is not meant to be shared by URL.

Progress is where real apps lose the most user trust: long forms, imports, onboarding flows, setup wizards, and any task where a refresh should not erase work.

Primitives ​

Progress primitives solve different kinds of unfinished work:

  • form-draft keeps one form's private field values alive.
  • wizard-draft keeps multi-step progress alive, including the current step and per-step data.

More progress primitives can live here as the category grows.

The Rule ​

If losing the state would make the user repeat work they already did, it probably belongs in progress durability.

If the state is already submitted, shared, auditable, or cross-device, it belongs on the server instead.

Good Examples ​

Progress durability is a good fit for:

  • A React Hook Form draft restored with reset().
  • An Inertia form draft restored with form.setData() or Object.assign(form, data).
  • A long profile, invoice, expense, or student form that should not disappear on refresh.
  • The current step in an onboarding flow.
  • The selected import method in a student import wizard.
  • Student rows entered across multiple steps.
  • Parsed CSV rows that should survive refresh before final submit.

Do Not Use Progress Durability For ​

  • Submitted records.
  • Passwords, tokens, OTPs, card details, or secrets.
  • Raw files.
  • State that should be shared with another person.
  • State that should sync across devices.

All open source projects are released under the MIT License.