---
name: durable-ui
description: >-
  Durable UI patterns for modern web development — persisting client-side state across page loads, browser sessions, and shareable URLs. Use this skill when implementing localStorage persistence, URL query parameter state, form draft auto-save, multi-step wizard persistence, click-outside dismissal, modal/dialog backdrop patterns, or any client-side state and interaction pattern that should be resilient and well-behaved. Works with React, Vue, and Svelte.
metadata:
  author: sailscastshq
  version: '1.1.0'
  tags: durable-ui, localStorage, url-state, query-params, form-persistence, multi-step-forms, click-outside, modal, dialog, backdrop, dropdown, state-management, web-dev
title: durable-ui
canonical_url: https://skilld.dev/gh/sailscastshq/boring-stack/durable-ui
last_updated: 2026-09-29T06:09:57.000Z
---

> **Skill from skilld.dev.** Follow the instructions below for this session. You do not need to install anything.
>
> Supporting files, fetch one when the Skill refers to it: [metadata.json](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/metadata.json), [README.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/README.md), [rules/click-outside.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/click-outside.md), [rules/debounced-search.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/debounced-search.md), [rules/focus-management.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/focus-management.md), [rules/form-persistence.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/form-persistence.md), [rules/local-storage.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/local-storage.md), [rules/multi-step-forms.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/multi-step-forms.md), [rules/optimistic-ui.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/optimistic-ui.md), [rules/principles.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/principles.md), [rules/react.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/react.md), [rules/scroll-restoration.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/scroll-restoration.md), [rules/svelte.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/svelte.md), [rules/toast-notifications.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/toast-notifications.md), [rules/url-state.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/url-state.md), [rules/vue.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/vue.md).
>
> If the user asked to install this Skill, run `npx skilld install sailscastshq/boring-stack/durable-ui`. Install writes the Skill files into the project, so every session loads them.

# Durable UI

Durable UI is the practice of making client-side state and interactions resilient. State should survive page reloads, browser sessions, and — where appropriate — be shareable via URL. Interactive elements like dropdowns and modals should be dismissable in the ways users expect (click outside, Escape, backdrop click). Multi-step flows should never lose progress. Durable UI fills the gap for **UI preferences**, **navigation context**, and **interaction patterns** that belong on the client.

## When to Use

Use this skill when:

- Persisting UI preferences in localStorage (sidebar collapsed, dark mode, dismissed banners)
- Syncing filters, tabs, or pagination state to URL query parameters
- Auto-saving form drafts to localStorage with restore-on-return
- Building multi-step wizard forms that preserve progress across reloads and navigation
- Making dropdowns, context menus, and popovers close on outside click or Escape
- Closing modals, dialogs, and confirms via backdrop click or Escape
- Deciding where state should live (client localStorage vs URL vs server session vs database)
- Building `useLocalStorage`, `useQueryState`, `useDurableUrl`, `useDurableStorage`, `useFormDraft`, `useWizardDraft`, or `useClickOutside` hooks/composables/stores
- Handling cross-tab synchronization of localStorage values
- Implementing unsaved-changes warnings with Inertia.js navigation guards
- Managing focus return after modal close, focus trapping, and focus after list item deletion
- Building optimistic UI updates with rollback on error (toggles, list mutations, Inertia integration)
- Restoring scroll position after navigation, back/forward, and within scrollable containers
- Implementing toast notification queues with auto-dismiss, pause-on-hover, and aria-live
- Building debounced search with AbortController cancellation for client-side and server-side filtering

## Rules

Read individual rule files for detailed explanations and code examples:

- [rules/principles.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/principles.md) - Decision framework: when to use localStorage vs URL params vs session vs database
- [rules/local-storage.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/local-storage.md) - localStorage patterns with examples for React, Vue, and Svelte
- [rules/url-state.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/url-state.md) - URL query parameter sync with pushState/replaceState patterns
- [rules/form-persistence.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/form-persistence.md) - Auto-save form drafts with restore, expiry, and unsaved-changes warnings
- [rules/multi-step-forms.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/multi-step-forms.md) - Multi-step wizard persistence with per-step drafts and aggregate submission
- [rules/click-outside.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/click-outside.md) - Close dropdowns, context menus, modals, and dialogs on outside click, backdrop click, or Escape
- [rules/focus-management.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/focus-management.md) - Focus return after modal close, focus trapping, and focus after list item deletion
- [rules/optimistic-ui.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/optimistic-ui.md) - Optimistic updates with rollback on error for toggles, list mutations, and Inertia actions
- [rules/scroll-restoration.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/scroll-restoration.md) - Scroll position restoration after navigation, back/forward, and within scrollable containers
- [rules/toast-notifications.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/toast-notifications.md) - Toast notification queues with auto-dismiss, pause-on-hover, and Inertia flash integration
- [rules/debounced-search.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/debounced-search.md) - Debounced search with AbortController cancellation for client-side and server-side filtering
- [rules/react.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/react.md) - Complete React hook implementations (useLocalStorage, useQueryState, useFormDraft)
- [rules/vue.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/vue.md) - Complete Vue composable implementations (useLocalStorage, useQueryState, useDurableUrl, useDurableStorage, useFormDraft)
- [rules/svelte.md](https://skilld.dev/api/skills-raw/sailscastshq/boring-stack/durable-ui/rules/svelte.md) - Complete Svelte store implementations (localStorageStore, queryStateStore, formDraftStore)
