
openfeature
OpenFeature vendor-agnostic feature flag SDK: installation, evaluation, providers. Use when implementing feature flags, A/B testing, or progressive rollouts.
- Installs
- 72
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/laurigates/claude-plugins --skill openfeature- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads openfeature automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
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.
When to Use
Automatic 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
Node.js (Server)
# Core SDK
npm install @openfeature/server-sdk
# Providers (choose one)
npm install @openfeature/go-feature-flag-provider # GO Feature Flag
npm install @openfeature/flagd-provider # flagd
npm install @openfeature/in-memory-provider # Testing
Node.js (Browser/React)
# Web SDK
npm install @openfeature/web-sdk
# React integration
npm install @openfeature/react-sdk
# Web providers
npm install @openfeature/go-feature-flag-web-provider
Python
uv add openfeature-sdk
uv add openfeature-provider-go-feature-flag # GO Feature Flag provider
Go
go get github.com/open-feature/go-sdk
go get github.com/open-feature/go-sdk-contrib/providers/go-feature-flag
Java
<dependency>
<groupId>dev.openfeature</groupId>
<artifactId>sdk</artifactId>
<version>1.7.0</version>
</dependency>
Rust
[dependencies]
open-feature = "0.2"
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
In-Memory Provider
import { OpenFeature } from '@openfeature/server-sdk';
import { InMemoryProvider } from '@openfeature/in-memory-provider';
// Configure test flags
const testProvider = new InMemoryProvider({
'new-feature': {
variants: {
on: true,
off: false,
},
defaultVariant: 'off',
disabled: false,
},
'button-color': {
variants: {
blue: '#0066CC',
green: '#00CC66',
},
defaultVariant: 'blue',
disabled: false,
},
});
// Use in tests
beforeAll(async () => {
await OpenFeature.setProviderAndWait(testProvider);
});
afterAll(async () => {
await OpenFeature.close();
});
Mocking in Unit Tests
import { vi } from 'vitest';
import { OpenFeature } from '@openfeature/server-sdk';
// Mock the entire SDK
vi.mock('@openfeature/server-sdk', () => ({
OpenFeature: {
getClient: vi.fn().mockReturnValue({
getBooleanValue: vi.fn().mockResolvedValue(true),
getStringValue: vi.fn().mockResolvedValue('test-value'),
}),
},
}));
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)
FAQ
What does the openfeature skill do?
OpenFeature vendor-agnostic feature flag SDK: installation, evaluation, providers. Use when implementing feature flags, A/B testing, or progressive rollouts.
How do I install openfeature?
Run npx skills add https://github.com/laurigates/claude-plugins --skill openfeature in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/openfeature/ (personal) or .claude/skills/openfeature/ (project).
Which AI agents can use openfeature?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is openfeature safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains openfeature?
It is published by laurigates in laurigates/claude-plugins. It has 72 recorded installs.
More from laurigates/claude-plugins
python-code-quality
laurigates/claude-plugins
Python code quality with ruff and ty. Use when the user mentions ruff, ty, linting, formatting, type checking, or Python code style.
ruff-linting
laurigates/claude-plugins
Python linting with ruff. Fast linting, rule selection, auto-fixing, and config. Use when checking Python code quality, enforcing standards, or finding bugs.
python-testing
laurigates/claude-plugins
Python testing with pytest, coverage, fixtures, and mocking. Use when the user mentions pytest, unit tests, coverage, fixtures, mocking, or writing Python tests.
pytest-advanced
laurigates/claude-plugins
Advanced pytest: fixtures, markers, parametrization, parallel execution. Use when implementing test infrastructure, writing fixtures, or running with coverage.
basedpyright-type-checking
laurigates/claude-plugins
Basedpyright static type checker for Python. Use when setting up type checking, configuring LSP, or comparing type checkers (basedpyright, pyright, mypy alternative).
uv-workspaces
laurigates/claude-plugins
Manage multi-package Python projects with uv workspaces. Use when the user mentions uv workspaces, Python monorepo, shared lockfiles, or member dependencies.
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work