feat: add capability-aware feature flag system#3229
Closed
rossnelson wants to merge 5 commits intomainfrom
Closed
Conversation
Add a typed feature flag store using persistStore for localStorage persistence and cross-tab sync. Exports featureFlags map store, isFeatureFlagEnabled derived helper, setFeatureFlag setter, and LocalFeatureFlag guard component for declarative usage. Includes storage event listener for cross-tab localStorage detection.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Replace the localStorage-only LocalFeatureFlag component with a CapabilityGuard that checks server capabilities first, falling back to localStorage when the capability is absent. Extends Capabilities type with serverlessWorkers for forward compatibility. Adds isCapabilityEnabled factory and withLocalFallback helper to capability-enablement.ts.
Replace the JSON map store with per-flag persistStore instances keyed
as featureFlags.<capabilityKey>. Removes isFeatureFlagEnabled and the
FeatureFlag type in favour of using keyof Capabilities directly.
Enable a flag via: localStorage.setItem('featureFlags.serverlessWorkers', 'true')
Comment on lines
+21
to
+24
| const serverValue = $page.data?.systemInfo?.capabilities?.[capabilityKey]; | ||
| if (serverValue !== undefined && serverValue !== null) { | ||
| return Boolean(serverValue); | ||
| } |
Collaborator
There was a problem hiding this comment.
Curious why we need this when below we do the same capability check in isCapabilityEnabled
Collaborator
Author
There was a problem hiding this comment.
It's not a redundant check. It ensures that the system-info value takes precedence. But i can see how the way its written makes it seem redundant. Ill update it to be more clear.
Replace the separate helper with inlined guard-clause logic and ?? operator to make the server-first, localStorage-fallback intent self-evident.
laurakwhit
reviewed
Mar 19, 2026
| ): Readable<boolean> { | ||
| if (!LOCAL_OVERRIDE_CAPABILITIES.has(key)) { | ||
| return derived(page, ($page) => | ||
| Boolean($page.data?.systemInfo?.capabilities?.[key]), |
Collaborator
There was a problem hiding this comment.
We also have page.data.namespace.namespaceInfo?.capabilities which is where workerHeartbeats is currently enabled/disabled. Maybe we want a distinction between isSystemCapabilityEnabled and isNamespaceCapabilityEnabled?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
featureFlagspersistStore holding aRecord<string, boolean>under thefeatureFlagslocalStorage key — the local override layerCapabilitiestype withserverlessWorkers?: boolean | nullfor forward compatibility with the protowithLocalFallbackandisCapabilityEnabledtocapability-enablement.ts— server capability is authoritative when present, localStorage is the fallback when absentCapabilityGuardcomponent for declarative feature gatingCleanShot.2026-03-19.at.09.51.55.mp4
How it works
truefalsetruetrueUsage
Enable locally until the server reports the capability:
Adding a new capability with local override = one line in
CAPABILITY_FLAG_MAP.Test plan
pnpm lintpasses with no new errorspnpm checkpasses with no new errorspnpm test -- --runpasses all unit tests with no regressionsCapabilityGuardrenders children when capability/flag enabled, fallback when disabled, nothing when disabled with no fallbackfalseoverrides localStoragetrue