Feature Flags System
This directory contains the feature flags implementation. Feature flags allow us to gradually roll out new features and control their visibility to different users.
Overview
The feature flags system is built using the flags/next package and integrates with Statsig for feature flag management.
📝 Note: For information about automatic flag revalidation and polling, see Flag Revalidation.
Usage
Client Components
For client components, you can use the Statsig hooks directly:
// @flowimport { useGateValue } from "@statsig/react-bindings";
export default function MyComponent() { const isEnabled = useGateValue("my_feature_flag");
return ( <div> {isEnabled ? ( <NewFeature /> ) : ( <LegacyFeature /> )} </div> );}Implementation Details
User Identification
The system uses a stable ID approach to ensure consistent feature flag evaluation for users:
- A stable ID is stored in a cookie
- If no stable ID exists, a new one is generated using crypto
- The stable ID is used to identify users in Statsig
⚙️ Statsig — userId length limitation
Statsig has a maximum userId length of 63 characters.
If a longer identifier is passed, Statsig will automatically truncate it and log an error.
➡️ Therefore, the UI must send a pre-trimmed userId (up to 63 characters) to Statsig.
It’s recommended to use a stable shortening or hashing method so that the same user always has the same userId in Statsig.
Flag Configuration
Each flag is configured with:
- A unique key
- A Statsig adapter for feature gate evaluation
- A default value
- User identification function
Adding New Flags
To add a new feature flag:
- Add a new flag definition in
@power-rent/lib/flags:
// @flowexport const myNewFeature = flag<boolean>({ key: 'my_new_feature', adapter: statsigAdapter.featureGate((gate) => gate.value), defaultValue: false, identify,});- Configure the flag in your Statsig dashboard
- Use the flag in your components as shown in the usage examples above
Best Practices
- Always provide a default value for flags
- Use Flow for type safety
- Keep flag names descriptive and consistent
- Clean up flags once they’re no longer needed
Updating Statsig Packages
The feature-flag integration uses two Statsig-related packages:
| Package | Purpose |
|---|---|
@flags-sdk/statsig | Thin wrapper for the flags runtime → Statsig. Has statsig-node-lite in its own deps but its version may differ from the one we pin. |
statsig-node-lite | Official lightweight Statsig SDK used on the server. We want exactly one version of this package across the repo. |
Why we focus on a single statsig-node-lite version
The goal is to avoid multiple copies of statsig-node-lite in the lock-file. Only one copy is needed, and pulling in different versions via transitive deps wastes install time and disk space.
@flags-sdk/statsig can be on any version that is compatible with the SDK, but we must ensure the SDK itself is deduped to a single version.
How to upgrade Statsig packages safely
-
Check the currently installed version (shown in yarn.lock):
Terminal window yarn why statsig-node-lite -
Decide which version you want to bump to (e.g.
0.4.5):Terminal window yarn add statsig-node-lite@0.4.5 -W # -W if you're using workspaces -
Verify the lock-file has only one
statsig-node-liteentry (useyarn list --pattern statsig-node-lite).
Troubleshooting
statsig-node-litedowngraded unexpectedly – another package may depend on a specific version. Useyarn why statsig-node-liteto locate the conflict.