OpenFeature SDK Integration
When to Use This Skill
| Use this skill when... | Use a sibling skill instead when... |
|---|---|
| You need the vendor-agnostic OpenFeature SDK API, hooks, and evaluation patterns | You need the GO Feature Flag (GOFF) self-hosted backend specifics — use go-feature-flag |
| You are choosing between providers or wiring an OpenFeature client into application code | You want to scaffold the full feature-flag stack (SDK + provider + CI) from scratch — use configure-feature-flags |
| Another skill needs the canonical reference for OpenFeature semantics | You want runtime detection of an existing feature-flag setup before changing anything — use configure-feature-flags |
Vendor-agnostic feature flag SDK providing standardized API across languages and providers. Use when implementing feature flags, A/B testing, canary releases, or progressive rollouts with any feature flag backend.
Activation triggers
- User mentions "feature flags", "feature toggles", or "feature management"
- User asks about A/B testing or canary releases
- User wants to implement progressive rollouts
- Project has OpenFeature SDK dependencies
- User mentions OpenFeature, flagd, or vendor-agnostic flags
Related skills:
go-feature-flag- Specific GO Feature Flag provider detailslaunchdarkly- LaunchDarkly provider integration
Core Concepts
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Application Code │
├─────────────────────────────────────────────────────────────┤
│ OpenFeature SDK (API) │
│ ┌─────────────┬──────────────┬─────────────┬─────────────┐ │
│ │ getBool() │ getString() │ getNumber()│ getObject()│ │
│ └─────────────┴──────────────┴─────────────┴─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Provider │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ GO Feature Flag │ flagd │ LaunchDarkly │ Split │ etc │ │
│ └─────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Flag Source │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ File │ S3 │ GitHub │ API │ ConfigMap │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Key Components
- API - Standardized interface for flag evaluation
- Provider - Backend-specific implementation
- Evaluation Context - User/request data for targeting
- Hooks - Lifecycle extensions for logging, telemetry
SDK Installation
Install the core SDK for the runtime plus one provider package (GO Feature Flag, flagd, or the in-memory provider for tests). Per-language install commands (Node.js server and browser/React, Python, Go, Java, Rust): see references/sdk-installation.md.
Basic Usage Patterns
Initialization
// TypeScript/Node.js
import { OpenFeature } from '@openfeature/server-sdk';
import { GoFeatureFlagProvider } from '@openfeature/go-feature-flag-provider';
// Initialize provider
const provider = new GoFeatureFlagProvider({
endpoint: process.env.GOFF_RELAY_URL || 'http://localhost:1031',
});
// Set provider (awaitable for ready state)
await OpenFeature.setProviderAndWait(provider);
// Get client
const client = OpenFeature.getClient('my-app');
Flag Evaluation
// Boolean flag
const isEnabled = await client.getBooleanValue('new-feature', false);
// String flag
const buttonColor = await client.getStringValue('button-color', '#000000');
// Number flag
const maxItems = await client.getNumberValue('max-items', 10);
// Object/JSON flag
const config = await client.getObjectValue('feature-config', {});
// With evaluation context
const context = { targetingKey: userId, email: userEmail, groups: ['beta'] };
const isEnabled = await client.getBooleanValue('new-feature', false, context);
Evaluation Context
// Creating context
const context: EvaluationContext = {
// Required: unique identifier for targeting
targetingKey: user.id,
// Optional: additional attributes for targeting rules
email: user.email,
groups: user.roles,
plan: user.subscription,
// Custom attributes
country: request.geoip.country,
browser: request.headers['user-agent'],
};
// Set global context (applies to all evaluations)
OpenFeature.setContext(context);
// Or per-evaluation context
await client.getBooleanValue('feature', false, context);
Hooks
import { Hook, HookContext, EvaluationDetails } from '@openfeature/server-sdk';
// Logging hook
const loggingHook: Hook = {
before: (hookContext: HookContext) => {
console.log(`Evaluating flag: ${hookContext.flagKey}`);
},
after: (hookContext: HookContext, details: EvaluationDetails<unknown>) => {
console.log(`Flag ${hookContext.flagKey} = ${details.value}`);
},
error: (hookContext: HookContext, error: Error) => {
console.error(`Error evaluating ${hookContext.flagKey}:`, error);
},
};
// Register globally
OpenFeature.addHooks(loggingHook);
// Or per-client
client.addHooks(loggingHook);
React Integration
import { OpenFeatureProvider, useFlag, useBooleanFlagValue } from '@openfeature/react-sdk';
import { GoFeatureFlagWebProvider } from '@openfeature/go-feature-flag-web-provider';
// Provider setup
const provider = new GoFeatureFlagWebProvider({
endpoint: import.meta.env.VITE_GOFF_RELAY_URL,
});
function App() {
return (
<OpenFeatureProvider provider={provider}>
<MyComponent />
</OpenFeatureProvider>
);
}
// Using flags in components
function MyComponent() {
// Simple boolean value
const isEnabled = useBooleanFlagValue('new-feature', false);
// Full flag details
const { value, isLoading, error } = useFlag('button-color', '#000');
if (isLoading) return <Spinner />;
return (
<div>
{isEnabled && <NewFeature />}
<Button color={value}>Click me</Button>
</div>
);
}
Testing
Use the in-memory provider for deterministic flag values in tests, or mock the SDK client in unit tests. Fixture and mock examples: see references/testing.md.
Best Practices
1. Initialize Early
// Initialize before app starts handling requests
async function bootstrap() {
await initializeFeatureFlags(); // First
await initializeDatabase();
await startServer();
}
2. Use Meaningful Flag Names
// Good: descriptive, namespaced
'checkout.new-payment-flow'
'dashboard.beta-analytics'
'api.rate-limit-v2'
// Bad: vague, unclear
'feature1'
'test-flag'
'enabled'
3. Always Provide Defaults
// Good: safe default that works if provider fails
const isEnabled = await client.getBooleanValue('risky-feature', false);
// Consider: what's the safe behavior if flags fail?
const maxItems = await client.getNumberValue('max-items', 100); // Safe limit
4. Handle Provider Errors
try {
const value = await client.getBooleanValue('feature', false);
} catch (error) {
// Log but don't crash - use default
logger.error('Feature flag evaluation failed', { error });
return defaultBehavior();
}
5. Clean Up Old Flags
// Track flag usage with hooks
const flagUsageHook: Hook = {
after: (context, details) => {
metrics.increment(`feature_flag.${context.flagKey}.evaluations`);
},
};
// Regularly review and remove flags with 100% rollout
// or flags that haven't been evaluated in months
Documentation
- OpenFeature Specification: https://openfeature.dev/specification
- SDK Reference: https://openfeature.dev/docs/reference/concepts/evaluation-api
- Providers List: https://openfeature.dev/ecosystem
- Hooks Guide: https://openfeature.dev/docs/reference/concepts/hooks
Related Commands
/configure:feature-flags- Set up feature flag infrastructure/configure:sentry- Error tracking (for feature flag rollback monitoring)
Scan to join WeChat group