Idea
Currently the user must explicitly choose between localStorageAdapter() (default) and indexedDBAdapter(). For users who don't know upfront how large their form data will be, this is a footgun:
- Start with localStorage (~5MB limit, ~5MB on iOS Safari)
- User uploads images / writes long markdown / fills out a rich-text editor
JSON.stringify(values).length quietly creeps over the limit
- Suddenly:
QuotaExceededError, persist fails, user loses everything on refresh
Proposed
A new adapter autoAdapter() (or option storage: 'auto') that:
- Defaults to
localStorageAdapter()
- On every write, measures the serialized payload size
- If size exceeds threshold (e.g., 1MB by default, configurable), transparently migrates to
indexedDBAdapter()
- Migrates existing data from localStorage to IndexedDB
- Continues using IndexedDB from that point on (no downgrade back to localStorage)
API sketch
```tsx
import { autoAdapter } from 'formdraft';
useFormDraft({
storage: autoAdapter({ thresholdBytes: 1_000_000 }),
// ...
});
```
Considerations
- Migration race: what if write fires during in-flight migration?
- Threshold tuning: 1MB safe for all browsers; some apps may want 500KB to be safer
- iOS Safari quota varies; may need probing-based threshold detection
- Should also handle the reverse case: if IndexedDB write fails (rare but possible), fall back to in-memory only with a warning?
Acceptance
- New
autoAdapter exported from main entry
- Tests: write small data → localStorage used; write large data → auto migration → IndexedDB used; subsequent reads correctly come from IndexedDB
- Documentation note in README explaining the trade-off (auto vs explicit)
Related
Discussed during v0.1.0-rc.1 documentation polish session (2026-05-27).
Idea
Currently the user must explicitly choose between
localStorageAdapter()(default) andindexedDBAdapter(). For users who don't know upfront how large their form data will be, this is a footgun:JSON.stringify(values).lengthquietly creeps over the limitQuotaExceededError, persist fails, user loses everything on refreshProposed
A new adapter
autoAdapter()(or optionstorage: 'auto') that:localStorageAdapter()indexedDBAdapter()API sketch
```tsx
import { autoAdapter } from 'formdraft';
useFormDraft({
storage: autoAdapter({ thresholdBytes: 1_000_000 }),
// ...
});
```
Considerations
Acceptance
autoAdapterexported from main entryRelated
Discussed during v0.1.0-rc.1 documentation polish session (2026-05-27).