Skip to content
Layers
Esc
navigateopen⌘Jpreview
On this page

Migration

Breaking-change policy and migration notes for semver releases.

Layers is pre-1.0. Breaking API changes are expected and ship in minor releases (e.g. 0.10.2), not majors. Treat semver as a signal, not a guarantee of zero breaks until 1.0 — see Stability & versioning.

How breaks are announced

  • Each intentional break gets a Changelog entry tied to a GitHub Release.
  • Step-by-step upgrade guidance lives on this page when a release requires consumer action.

0.x — wired handles and observe reshape

Three coordinated 0.x changes: wired handles (createLayer / useLayer), observe hooks return arrays, and stack lookup semantics tightened.

Observe: useLayer(key, …)useLayerState({ key, … })

The old useLayer was observe-only and returned a single LayerState | null. It is now useLayerState and returns LayerState[] — empty when nothing matches.

Per-key queued observation is useLayerQueuedState({ key, … }). Whole-stack queued observation is useQueuedStack({ stack?, select?, compare? }).

Stack hooks: positional args → options bag

Optional trailing client?: LayerClient is unchanged.

Wire: useLayer(options).open(payload)

client.open({ …layerOptions, payload }) remains valid. Wired handles bind identity and expose payload-only ops:

Headless (no adapter): createLayer(options, client) from @stainless-code/layers. On Svelte adapters, import that factory as createLayerHandlecreateLayer is the wired handle.

Core: LayerStack.find is topmost same-key

find(key) now returns the topmost mounted layer with that key signature (findLast), not the first. Matters in parallel stacks with duplicate keys.

Core: cancelQueued optional { id }

On LayerStack: cancelQueued(key, response, opts?: { id? }). Omit id → first-queued (FIFO) for the key; pass id → exact queued match.

Adapter entry names

Role React / Preact / Solid / Vue / Lit Angular Alpine Svelte
Wired useLayer injectLayer (useLayer alias) createLayer createLayer
Mounted per-key useLayerState injectLayerState createLayerState createLayerState
Queued stack useQueuedStack injectQueuedStack useQueuedStack createQueuedStack
Queued per-key useLayerQueuedState injectLayerQueuedState createLayerQueuedState createLayerQueuedState

0.x — omit dismiss response when void

Toasts and other void-result layers no longer need call.end(undefined). Omit the response whenever undefined extends R — same rule as omitting .open()’s payload (PayloadArg / EndArgs). Applies to call.end/dismiss, stack dismiss/dismissAll/cancelQueued, and handle dismiss/cancelQueued.

Type tighten: LayerHandle.dismiss / cancelQueued used to accept a missing response for every R. Bare handle.dismiss() is now an error when R does not admit undefined (pass true/false for confirms).

LayerClient.dismissAll / LayerGroup.dismissAll stay loosely typed (response?: unknown) — stacks on a client are heterogeneous.

Last updated on August 8, 2026

Was this page helpful?