Summary
useStack falls back to a module-scoped singleton (fallbackStack) when no provider/context exists. In SSR (long-lived Node process), overlay tickets registered into this global persist across requests and aren't cleaned up — causing cross-request state bleed (wrong z-index) and unbounded memory growth.
Location
packages/0/src/composables/useStack/index.ts:359-365 — let fallbackStack + lazy getStackFallback().
:408-410 — useStack() returns the fallback when !instanceExists() (and on a useContext miss).
:276 cleanup is onScopeDispose, which is unreliable server-side.
- Documented mitigation already present (
:375): "For SSR safety, use createStackPlugin to provide isolated context per app."
Impact
Partial / low. Requires SSR + an overlay component (Dialog / Popover / Snackbar) used without createStackPlugin — which the JSDoc already flags as the wrong SSR setup. Note the "cross-request data leakage" framing (from the source review) is overstated: these are z-index tickets, not user data — it's state bleed + memory growth, not data exfiltration. Aligns with the composable-bar's SSR-hardening priority.
Suggested fix
Guard the fallback under SSR: either throw when no context is provided server-side, or return an ephemeral per-call createStack() (no shared global) on the server, steering consumers to createStackPlugin for coordinated SSR z-index. Add an SSR test.
Summary
useStackfalls back to a module-scoped singleton (fallbackStack) when no provider/context exists. In SSR (long-lived Node process), overlay tickets registered into this global persist across requests and aren't cleaned up — causing cross-request state bleed (wrong z-index) and unbounded memory growth.Location
packages/0/src/composables/useStack/index.ts:359-365—let fallbackStack+ lazygetStackFallback().:408-410—useStack()returns the fallback when!instanceExists()(and on auseContextmiss).:276cleanup isonScopeDispose, which is unreliable server-side.:375): "For SSR safety, use createStackPlugin to provide isolated context per app."Impact
Partial / low. Requires SSR + an overlay component (
Dialog/Popover/Snackbar) used withoutcreateStackPlugin— which the JSDoc already flags as the wrong SSR setup. Note the "cross-request data leakage" framing (from the source review) is overstated: these are z-index tickets, not user data — it's state bleed + memory growth, not data exfiltration. Aligns with the composable-bar's SSR-hardening priority.Suggested fix
Guard the fallback under SSR: either throw when no context is provided server-side, or return an ephemeral per-call
createStack()(no shared global) on the server, steering consumers tocreateStackPluginfor coordinated SSR z-index. Add an SSR test.