Implementation Notes
Internal lifecycle, snapshots, and promise settlement details.
Implementation Notes
This page is about the current implementation details that matter to power users.
Store shape
Internally, the runtime is a Store<OverlayState> where state looks like:
{ items: OverlayItem[] }Each item contains:
idtypepropsstatuscreatedAt
Promise settlement path
createOverlayStore() keeps a pendingResolvers map keyed by overlay id.
open()creates an item and a pending promiseclose()settles that promise with the provided resultremove()settles withundefinedonly if the item was not already closingclear()settles every pending promise withundefined
That means promise settlement is tied to item lifecycle, not just rendering.
Lifecycle path
The current item flow is:
open()adds{ status: 'open' }close()changes status toclosingremove()deletes the item from the store
close() and remove() are separate on purpose.
Provider and host wiring
OverlayProvider creates a store if one is not passed, provides { store, adapters } through context, and mounts OverlayHost after children.
That default host mounting means a normal app usually does not need to render OverlayHost manually.
Snapshot path
useOverlayItems() uses useSyncExternalStore with:
store.subscribestore.getSnapshotstore.getInitialSnapshot
So the low-level read path is already aligned with React's external-store subscription model.