As engineering teams contend with the constant demand for increased speed and efficiency in their development practices, the rules around compliance and security remain rigid. This presents one of the core problems we see teams struggling with today:
How can we move fast, with safety?
Pete Hodgson, OpenFeature Governance Board Member, poses this question in his foreword for the new guide the Flagsmith team put together with OpenFeature and eBay.
For large organisations operating in complex or regulated environments, the question is particularly salient. Feature flags form part of the answer (in support of Continuous Delivery), but only if introduced in the right way. Large organisations face a steep learning curve when introducing any new technology, and feature flags are no exception.
Because feature flags live deep in your codebase, it’s important to introduce them in a thoughtful and strategic way, avoiding locking you into bad habits or specific vendors.
Feature flags are more of a social innovation than a technical one. Their real magic is revealed when they’re introduced to an organisation at scale—impacting the very way software gets built. The technology is only half the battle. Determining how to use it, who can use it, and how to drive adoption successfully is just as important.
Doing a good job of introducing any new technology into a large organisation starts with people—the people behind the technology and the internal teams who will adopt it.
Introducing feature flags will fundamentally change the way you build software, so pulling in the right stakeholders from the beginning is important. Start by creating a working group with representatives from your engineering, QA, product, and DevOps/infrastructure teams.
Additionally, you’ll need full executive buy-in to bring flags on at scale. This is true from a budget perspective but, just as importantly, from a time perspective, too. Part of the reason the eBay team was so successful with their OpenFeature adoption is because they were given full license to use engineering hours to get it done.
Budget for this time up front and create a plan with specific milestones and owners—as well as a strict timeline, so that the project keeps moving forward. Ensure this plan is shared at a company level, so that those involved are motivated to stay on time and on track.
eBay leaned into three main levers to drive organisational-wide adoption:
As you begin to determine how to introduce feature flags into your release processes, ensure your team is familiar with the different kinds of flags as well as best practices to keep your flags healthy and reduce tech debt. Feature flags can become an anti-pattern if over-engineered, so be sure to familiarise yourself with the different types of flags and lifecycles.
Another best practice for getting up and running with flags is to identify the simplest possible use case, start there, and then gradually introduce them more widely and in more complex use cases.
Creating governance for your feature flag usage is going to be a key part of this adoption. This article is a sneak preview of the full guide on scaling feature flags.
If you enjoyed it and want to read on, you can download the full (ungated) guide with the case study here.
]]>This year's KubeCon EU was located in London, where I happen to live, giving me the opportunity to attend KubeCon EU for the first time. I had a wonderful time finally meeting fellow OpenFeature maintainers face-to-face and connecting with users of OpenFeature.
This year we saw a growth of interest in OpenFeature, and heard stories of people using OpenFeature in their own products. The OpenFeature booth at the project pavillion buzzed with activity, plenty of knowledge shared and the power of OpenFeature shared with interested people.
For a second time at KubeCon our dedicated, co-located event, The OpenFeature Summit took place the day before KubeCon EU 2025 itself. The summit featured great talks and speakers. I would like to point of a few of these talks:
▶️ OpenFeature Update From the Maintainers - Thomas Poignant, Lukas Reining & Alexandra Oberaigner Latest updates what happened in the world of OpenFeature.
▶️ OpenFeature’s Positive Impact on Confidence at Dynatrace - Simon Schrottner & Todd Baert, Dynatrace by Simon Schrottner & Todd Baert from Dynatrace gave a great presentation about how they internally use the different OpenFeature offerings like flagd, OpenFeature SDKs
▶️ Canary Deployments Are a Myth - True Progressive Delivery Occurs Via OpenFeature - Bob Walker, Octopus Deploy by Bob Walker from Octopus Deploy described how they solved they delivery problems using OpenFeature and feature flags. A deep dive how flags can help with deploying releases in a safe and convenient manner. Tip! A longer version of this talk is available as part of KubeCon EU 2025.
▶️ Lightning Talk: OpenFeature Multi-Provider: Enabling New Feature Flagging Use-Cases by Jonathan Norris from DevCycle. A talk about ways you can use the new Multi-Provider to your benefit, like to migrate away from feature flag solution to your new one.
▶️ Challenges in Distributed Feature Flag Evaluation and How To Solve Them Lukas Reining & Christopher Bohlen, codecentric AG by Lukas Reinig & Christopher Bohlen from codecentric AG. In this talk we got into the nitty gritty of feature flags that span multiple services, and saw multiple proposals how we can ensure the feature flag evaluations are consistent between the services.
During the conference we also introduced our latest creation, OpenFeature CLI, which streamlines how feature flags are managed within your codebase. The tool generates a type-safe OpenFeature client based on a flags manifest file that either can be pulled from supported feature flag systems or sourced from a JSON file.
With OpenFeature CLI, developers can:
The CLI represents our commitment to improving developer experience and making feature flag management more accessible to teams of all sizes. It's designed to work alongside your existing tools and workflows with minimal friction.
In a separate article, we will dive deeper into the goals of openfeature-cli
and how it can improve a developer's experience working with feature flags. Stay tuned for a hands-on tutorial.
KubeCon EU 2025 was a milestone event for the OpenFeature community. The growing adoption of OpenFeature across diverse organizations demonstrates the industry's recognition of standardized feature flagging as a critical component of modern software delivery.
We'd like to thank everyone who visited our booth, attended the summit, or participated in OpenFeature-related discussions throughout the conference. Your enthusiasm and feedback drive our project forward.
We'd love to welcome you into the OpenFeature community. You can join our Slack channel, attend our bi-weekly community meeting or just check out our GitHub repository.
The Sentry OpenFeature Hook allows Sentry to track feature flag evaluations within your application. When an error occurs, Sentry will include the state of all evaluated feature flags in the error report, providing crucial context for debugging and troubleshooting.
This integration is currently in beta and only supports boolean flag evaluations. See their changelog for details on how feature flags are integrated into their platform.
To use the Sentry OpenFeature Hook in your JavaScript application:
import * as Sentry from "@sentry/browser";
import { OpenFeature } from "@openfeature/web-sdk";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
integrations: [Sentry.openFeatureIntegration()],
});
OpenFeature.setProvider(new MyProviderOfChoice());
OpenFeature.addHooks(new Sentry.OpenFeatureIntegrationHook());
const client = OpenFeature.getClient();
const result = client.getBooleanValue("test-flag", false); // evaluate with a default value
Sentry.captureException(new Error("Something went wrong!"));
Requirements: Sentry SDK version 8.43.0 or higher
For Python applications, you can use the Sentry OpenFeature Hook as follows:
import sentry_sdk
from sentry_sdk.integrations.openfeature import OpenFeatureIntegration
from openfeature import api
// Initialize Sentry with the OpenFeature integration
sentry_sdk.init(
dsn="https://examplePublicKey@o0.ingest.sentry.io/0",
integrations=[
OpenFeatureIntegration(),
],
)
// Get your OpenFeature client
client = api.get_client()
// Evaluate a feature flag
client.get_boolean_value("hello", default_value=False)
// If an error occurs, Sentry will include the feature flag state
sentry_sdk.capture_exception(Exception("Something went wrong!"))
Requirements: sentry-sdk >= 2.19.2, openfeature-sdk >= 0.7.1, Python >= 3.8
The Sentry OpenFeature integration provides several key benefits:
Contextual Error Reporting: When errors occur, you'll see exactly which feature flags were active, helping you identify if a flag change contributed to the issue.
Performance Monitoring: Track how feature flags impact your application's performance.
Debugging Efficiency: Reduce the time spent reproducing issues by having feature flag state automatically included in error reports.
Release Confidence: Make data-driven decisions about feature rollouts by correlating errors with specific flag states.
This integration exemplifies the power of open standards in the feature flagging ecosystem. By implementing the OpenFeature specification, Sentry can provide a seamless integration that works with any OpenFeature provider, without requiring vendor-specific implementations.
This aligns with OpenFeature's vision of reducing integration effort by moving from effort(N*M) to effort(N+M). OpenFeature delivers a standardized feature flagging SDK, already implemented by most providers, and Sentry can focus on building a great performance monitoring and error-tracking platform for their users.
If you're using Sentry and OpenFeature, we encourage you to try out this integration. The feature flag state will be automatically included in your error reports, providing valuable context for debugging.
For more information, check out the official Sentry documentation:
Using another platform? Sentry is planning expanding support for more platforms, starting with mobile. We're excited to see how this integration helps teams better understand the impact of their feature flags on application stability and performance.
]]>The Flags SDK is an exciting development for standardizing feature flagging in Next.js and SvelteKit, as it takes an opinionated approach to how feature flags should be used:
// flags.ts
import { createOpenFeatureAdapter } from "@flags-sdk/openfeature"
import { dedupe, flag } from "flags/next";
import type { EvaluationContext } from "@openfeature/server-sdk";
// pass an init function, and return the client
const openFeatureAdapter = createOpenFeatureAdapter(async () => {
const provider = new YourProviderOfChoice()
await OpenFeature.setProviderAndWait(provider);
return OpenFeature.getClient();
});
const identify = dedupe((async ({ headers, cookies }) => {
// Your own logic to identify the user
// Identifying the user should rely on reading cookies and headers only, and
// not make any network requests, as it's important to keep latency low here.
const user = await getUser(headers, cookies);
const context: EvaluationContext = {
targetingKey: user.id,
// .. other properties ..
};
return context;
}));
export const exampleFlag = flag<boolean, EvaluationContext>({
key: "example-flag",
defaultValue: false,
identify,
adapter: openFeatureAdapter.booleanValue(),
});
// page.tsx
import { exampleFlag } from "../flags";
export default async function Page() {
const banner = await exampleFlag();
return (
<div>
{banner ? <Banner /> : null}
{/* other components */}
</div>
);
}
This adapter will allow most Node.js OpenFeature Providers to work with the Flags SDK, though there may be some compatability issues with certain Node.js OpenFeature Providers with the Vercel Edge Runtime that should be tested per-provider.
The integration demonstrates a key aspect of OpenFeature's vision - moving from effort(N*M) to effort(N+M). OpenFeature delivers a standardized feature flagging SDK, already implemented by most providers, and Vercel can focus on building a wonderful framework-specific developer experience on top of that foundation.
We are excited to continue working with the team at Vercel that is leading this effort, and to help expand the efforts of open standards in feature flagging for Next.js and SvelteKit. One of the visions of OpenFeature has always been deeper integration into the language / framework level as the adoption of OpenFeature continues to grow, we are happy to work with language and framework authors who strive to offer feature flagging built-in.
While the Flags SDK is offering Next.js and SvelteKit developers with an opinionated and performance optimized open-source feature flagging SDK, we recognize that its structure may not work for all Next.js developers out there relying on a mixture of client-side rendering in their applications. If you are knowledgeable about Next.js and would like to help OpenFeature develop our Next.js SDK, please reach out to us in the CNCF #openfeature Slack.
If you'd like to test out the Flags SDK OpenFeature Adapter check out their example project.
]]>This year, teams tackled projects ranging from OpenFeature CLI improvements to using OpenFeature Remote Evaluation Protocol with CloudFlare Workers. Let's take a closer look at how our team hacked, what we learned, and why these projects matter.
At DevCycle, we were an early supporters of the OpenFeature Remote Evaluation Protocol (OFREP), and long-time users of Cloudflare Workers. Naturally, we were curious if we could use the OFREP API as a bridge interface to better support Feature Flags in these edge environments. As one of our hackathon projects, Elliot from our team built a DevCycle OFREP Worker, which we could publish for customers to run in their own environment. This worker can use a service binding to bind this worker to any of their own internal workers.
This implementation provides a Cloudflare Worker template that synchronizes and caches DevCycle flags configuration within your Cloudflare environment. The worker fetches the flag configuration from the DevCycle's CDN once, which is served by Cloudflare's CDN / R2, and then processes the project configuration locally to evaluate flags for individual users. This means that feature flags can be accessed almost instantaneously within any Worker in your environment, eliminating processing delays and reducing external API calls.
Then, in your internal worker, you can use the existing OpenFeature SDKs with the OFREP Provider to bind the fetch call to the DevCycle OFREP Worker:
import { OpenFeature } from '@openfeature/server-sdk'
import { OFREPProvider } from '@openfeature/ofrep-provider'
const provider = new OFREPProvider({
baseUrl: 'https://ofrep-bucketing-worker.devcycle.com',
fetchImplementation: (input: RequestInfo | URL, init?: RequestInit) => env.OFREP_BUCKETING.fetch(input, init),
headers: [
['Content-Type', 'application/json'],
]
})
await OpenFeature.setProviderAndWait(provider);
const client = OpenFeature.getClient();
Integrating OFREP with Cloudflare Workers offers a scalable and high-performance solution for feature flag evaluation at the edge built on open standards. This was a great demo during our Hackathon; there is still some work to do to productize this OFREP worker; reach out to us if you think this is an interesting use-case for OFREP as we continue to work on it.
Strongly typed feature flags are essential for teams managing feature flags at scale across large codebases.
DevCycle has long supported the dvc generate types
command in our CLI, which generates Typescript Types for our DevCycle SDKs.
When we heard about the development progress of the OpenFeature CLI in generating types for OpenFeature SDKs, we were eager to contribute to its development.
While the OpenFeature CLI is in its early development, type generation for Go and React is already functional. However, there was no built-in way for vendors to integrate their platforms with the CLI’s type generation feature.
The openfeature generate react
command runs by generating a typed interface for your OpenFeature SDK from a known list of flags from a standard flags manifest file.
To support this standard as a vendor, the CLI would need a way to pull and sync the flag manifest file directly from a vendor’s platform.
Jason from DevCycle stepped in and created an openfeature pull
method to pull flag data from DevCycle's API and generate a manifest file for the CLI to use.
> openfeature pull
> openfeature generate react
This will result in an openfeature.ts
file with populated variable hooks:
'use client';
import {
type ReactFlagEvaluationOptions,
type ReactFlagEvaluationNoSuspenseOptions,
type FlagQuery,
useFlag,
useSuspenseFlag,
} from "@openfeature/react-sdk";
/**
*
*
* **Details:**
* - flag key: `a-newer-feature`
* - default value: `false`
* - type: `boolean`
*/
export const useANewerFeature = (options?: ReactFlagEvaluationOptions): FlagQuery<boolean> => {
return useFlag("a-newer-feature", false, options);
};
/**
*
*
* **Details:**
* - flag key: `a-newer-feature`
* - default value: `false`
* - type: `boolean`
*
* Equivalent to useFlag with options: `{ suspend: true }`
* @experimental — Suspense is an experimental feature subject to change in future versions.
*/
export const useSuspenseANewerFeature = (options?: ReactFlagEvaluationNoSuspenseOptions): FlagQuery<boolean> => {
return useSuspenseFlag("a-newer-feature", false, options);
};
...
We are excited to keep working on the CLI with the folks from Dynatrace, Google Cloud, and others leading this effort. Our PR adding the pull command
Building a Codemod for OpenFeature migrations has been on our radar for a while. After connecting with the Codemod team, we saw its potential for helping customers migrate from vendor SDKs to OpenFeature SDKs. Codemod has gained great adoption among teams upgrading to the latest versions of React or officially supported upgrade paths - such as the transition from Nuxt 3 to Nuxt 4 (Nuxt 3 → 4).
This hackathon finally gave us the chance to experiment with Codemod’s tooling and publish a codemod. Think of the codemod platform as tooling around open-source code transformation tools like jscodeshift, while adding AI-powered tooling for generating codemods, plus an NPM-like repository for distributing them.
Our first set of codemods focussed on helping teams transition their codebases from DevCycle or Launchdarkly Node.js SDKs to using the OpenFeature SDK, using the respective vendor’s OpenFeature Provider. To do this, we discovered it best to break down the problem into smaller, testable steps and then run all the codemods together in a workflow:
initializeDevCycle()
to setting up the DevCycleProvider
and creating the OpenFeature ClientDevCycleUser
to EvaluationContext
objects, rename user_id
param to targetingKey
variableValue()
and variable()
calls with get<Type>Value()
and get<Type>Details()
calls to OpenFeatureAfter installing codemod: npm i -g codemod
, these can be run using:
codemod devcycle-to-openfeature-nodejs-workflow
The codemod CLI will download the latest version of the codemods and run them against your codebase.
These codemods are a great starting point for anyone looking to do much of the heavy lifting, updating a codebase from DevCycle or Launchdarkly Node.js SDKs to OpenFeature. We are interested in feedback from the community about the value of these codemods and if we should continue developing them for more languages / vendors, as well as if these codemods would make sense as an OpenFeature-supported project.
Docusaurus is a popular framework for building documentation websites, making it easy to create and maintain interactive docs using Markdown and React. Since both DevCycle and OpenFeature rely on Docusaurus for their documentation, integrating feature flagging directly into the platform makes perfect sense. With this approach, documentation can dynamically update based on feature flags, allowing teams to release code and docs together—an essential capability for feature-driven development.
For the OpenFeature Hackathon, one of our engineers, Parth, built an OpenFeature Docusaurus plugin, leveraging the OpenFeature React SDK and flagd to enable feature management within documentation sites. He created a Docusaurus provider and applied it to a barebones Docusaurus site to showcase its functionality. The plugin allows developers to use feature flags to dynamically toggle sections of documentation, ensuring content remains in sync with evolving product features. By integrating OpenFeature, this project bridges the gap between documentation and feature flagging, improving flexibility, maintainability, and release coordination for teams using Docusaurus.
DevCycle has been supporting OpenFeature for several years, and as part of this hackathon, Jamie took the time to review our OpenFeature providers across our SDKs to ensure they were up-to-date with the latest OpenFeature SDK features.
This included adding event tracking support and handling initialization/close when applicable.
We also worked on building and publishing our much requested DevCycle OpenFeature Ruby Provider. Our goal is to provide OpenFeature support across all DevCycle SDKs, with only Next.js, iOS, Android, React Native, Flutter, and Roku remaining for full coverage.
In the spirit of dogfooding OpenFeature and our own Providers, Kaushal from our team took up the task of updating the usage of DevCycle's Nest.js SDK in our main API service to use the OpenFeature Nest.js SDK with DevCycle's Nest.js Provider.
To accomplish this, we introduced a wrapper service that used a single instance of the OpenFeature Client, making it accessible across our Nest.js service. This straightforward migration allowed the OpenFeature Client to replace any existing calls to DevCycle's SDK.
One of the key takeaways from this project was realizing how much our API development relied on Nest.js decorators, which simplified our feature flagging of API endpoints:
@RequireFlagsEnabled(["flag1", "flag2"], ForbiddenException)
NotFound
)@RequireFlagValues({ "flag1": "apples", "flag2": true }, ForbiddenException)
NotFound
)We started a PR here to enhance the Nest.js SDK with these decorators.
We also lean heavily on the mock interfaces provided by the DevCycle Nest.js SDK to mock and set flag values, which allows us to test different branching code paths in our API service. Adding similar mocking capabilities would be a useful addition to make testing all the OpenFeature SDKs easier. Dogfooding the OpenFeature SDKs and our own providers was a valuable learning experience, sparking new ideas on how to contribute to and improve these SDKs in the future.
And many more! Each project aimed to strengthen the OpenFeature ecosystem and provide better tools for developers. Let us know what projects you found the most interesting and we should continue developing further, please reach out to us in the CNCF #openfeature Slack.
]]>OpenFeature is a CNCF-incubating project that's defining open standards for feature flagging and experimentation. As a vendor-agnostic initiative, we're committed to improving the developer experience across the feature flagging landscape.
Key highlights:
As key players in the feature flagging ecosystem, your insights are invaluable to shaping our specifications and improving the developer experience of consuming feature flags in codebases.
We're flexible and open to structuring participation in a way that works best for our advisors.
If your organization is involved in the feature flagging space - whether as a commercial vendor or an open-source maintainer - and you're interested in joining the OpenFeature Vendor Council, we'd love to hear from you!
Please reach out to us by:
In your message, please include:
The OpenFeature project is committed to creating standards that benefit the entire feature flagging ecosystem. By bringing together diverse perspectives from across the industry, we can build something truly valuable for developers and organizations alike.
We look forward to collaborating with you!
]]>The OpenFeature Summit is the ultimate gathering for feature flagging enthusiasts to exchange insights, best practices, and success (and a few horror) stories. This event is a fantastic opportunity to network, engage in lively discussions, and explore the latest innovations in feature flagging.
Event Details:
The OpenFeature Summit is a co-located event held the day before KubeCon EU and requires an all-access pass.
Schedule Highlights:
For more details, visit our OpenFeature Summit page.
In addition to the OpenFeature Summit, there will also be several sessions during KubeCon EU:
OpenFeature Update from the Maintainers - Thomas Poignant, Adevinta & Lukas Reining, codecentric AG
How We Progressively Deliver Changes To Kubernetes Using Canary Deployments and Feature Flags - Bob Walker, Octopus Deploy
Type-safe Feature Flagging in OpenFeature: Lessons Learned From Using Feature Flags at Google - Michael Beemer, Dynatrace & Florin-Mihai Anghel, Google
Don't miss the chance to visit our booth in the project pavilion! We'll be there to answer your questions, demonstrate our latest features, and discuss how OpenFeature can help your organization.
Booth Location: Solutions Showcase
Schedule:
We are still looking for sponsors for our co-located event. If you're interested in supporting the OpenFeature Summit and gaining visibility among a highly engaged audience, please review the sponsorship prospectus.
We look forward to seeing you at KubeCon EU and the OpenFeature Summit!
]]>As usual, we had a great time at the OpenFeature booth in the project pavilion. We always appreciate the chance to connect with maintainers face-to-face, sometimes for the first time! Each year we hear from more users who've made use of OpenFeature within their organization or project.
This was also our first time having our own dedicated, colocated event: The OpenFeature Summit! There were some great talks here; a couple of highlights:
The full list of videos and slides from the OpenFeature Summit are available here.
Additionally, don't sleep on Pete Hodgson's SDLC track presentation on undertaking big, hairy migrations, and how feature flags can help.
Teams spend a lot of time talking about developing, deploying, monitoring and maintaining features, but how do you know if you've built the right features in the first place? Without data to evaluate the success and adoption of features, aren't you just guessing? The best teams bake experimentation into their product development cycle, so that they can use data to drive their decisions.
Some feature flag vendors provide functionality to help address this issue, and we knew OpenFeature needed to as well. With the latest enhancements to our specification, OpenFeature now supports this sort of experimentation! The new Tracking API defines interfaces and functions to allow application authors to "close the gap" between feature flags and business objectives; helping to assert that a particular flag variant actually corresponds to increased usage, for instance.
In fact, if your vendor or home-grown feature flag solution doesn't support equivalent functionality, hooks and tracking compose a flexible solution to associate flag evaluations with usage data, regardless of whatever customer data platform or telemetry backend you use. For more information, see tracking concepts.
These enhancements were brought to you by the hard work of many feature flag vendors, enterprises, and subject matter experts... Thanks to all who helped!
Tracking event functionality is already implemented in our React, Javascript, Java, and Go SDKs, with more on the way. For an up-to-date list of implementations, check out the SDK Compatibility Overview. Download the latest release in your language of choice and try it out!
]]>Max’s journey with OpenFeature began around a year ago while working at Justworks, where his team was re-evaluating their flagging strategy. He noticed that the Ruby SDK existed and had the basics of flag evaluation implemented but was not yet released or highlighted on the website.
“At Justworks, I wrote our implementation to get us going, but I started to upstream many of our learnings into the Ruby SDK. We dropped support for our internal implementation last month and are now entirely on the main SDK,” Max explains.
Max is passionate about increasing Ruby’s presence within Cloud Native Computing Foundation (CNCF) projects, where he feels it doesn’t get as much attention as other languages. As he puts it, “Ruby is largely underrepresented in many CNCF projects; the Ruby community tends to have its own handful of competing libraries but doesn’t interact externally as much as other languages like Golang and Java.”
Beyond his focus on Ruby, Max also feels a strong sense of responsibility to give back to the open-source community. “I owe a great deal to the open-source community and feel like OpenFeature is an excellent project to give back on, as the implementation is straightforward, and I actively use it at Justworks,” he says.
Max’s key contributions to the OpenFeature project have focused primarily on the Ruby SDK. Some of his major achievements include:
These contributions have greatly improved the usability and functionality of the Ruby SDK, helping it gain more traction within the OpenFeature ecosystem.
For Max, one of the most fulfilling moments in his OpenFeature contributor journey was seeing the Ruby SDK officially listed on the OpenFeature website. As he reflects, “Definitely getting the Ruby SDK listed on the website was a big milestone.”
What made this achievement even more meaningful for Max was that it marked his debut in large-scale open-source contributions. “It was my first time participating in a large open-source project, and that was very rewarding,” he shares, emphasizing the impact of his work on the broader OpenFeature community.
When offering advice to newcomers, Max suggests starting with the foundation. “Start with the basics in the specification!” he advises, noting that, “Unlike other standards and specs around the web, OpenFeature is very straightforward and digestible, and you can read the whole thing in less than an hour.”
Max encourages new contributors to explore whether their primary language is represented or if the vendor they use has a provider. Once you find something that sparks your interest, his advice is simple: “Just start coding!”
He adds that contributors shouldn’t hesitate to ask for support, because “the OpenFeature community is very friendly, and welcomes all questions on Slack or GitHub.”
We’re grateful for Max’s dedication and contributions to the OpenFeature project. His work has had a significant impact, and we look forward to seeing how he continues to shape the future of feature flagging standards.
]]>The OpenFeature Summit is the ultimate gathering for feature flagging enthusiasts to exchange insights, best practices, and success (and a few horror) stories. This event is a fantastic opportunity to network, engage in lively discussions, and explore the latest innovations in feature flagging.
Event Details:
The OpenFeature Summit is a co-located event held the day before KubeCon NA and requires an all-access pass.
Schedule Highlights:
For more details, visit our OpenFeature Summit page.
In addition to the OpenFeature Summit, there will also be several sessions during KubeCon NA:
Taming Your Application’s Environments - Marcos Lilljedahl, Dagger & Mauricio "Salaboy" Salatino, Diagrid
Migratory Patterns: Making Architectural Transitions with Confidence and Grace - Pete Hodgson, PartnerSlate
Don't miss the chance to visit our booth at the Solutions Showcase! We'll be there to answer your questions, demonstrate our latest features, and discuss how OpenFeature can help your organization.
Booth Location: Salt Palace | Level 1 | Halls A-C + 1-5 | Solutions Showcase
Schedule:
We are still looking for sponsors for our co-located event. If you're interested in supporting the OpenFeature Summit and gaining visibility among a highly engaged audience, please review the sponsorship prospectus.
We look forward to seeing you at KubeCon NA and the OpenFeature Summit!
]]>The Angular SDK exports a module that allows you to configure your OpenFeature provider using Angular constructs.
You can set your default provider, and optionally configure additional providers for other domains.
Besides configuring your provider, you'll also need to use the OpenFeatureModule
in order to utilize the other features of the SDK.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OpenFeatureModule } from '@openfeature/angular-sdk';
@NgModule({
declarations: [
// Other components
],
imports: [
CommonModule,
OpenFeatureModule.forRoot({
provider: new YourOpenFeatureProvider(),
// domainBoundProviders are optional, mostly needed if more than one provider is needed
domainBoundProviders: {
domain1: new YourOtherOpenFeatureProvider(),
domain2: new YourOtherOtherOpenFeatureProvider(),
},
})
],
})
export class AppModule {
}
Perhaps the most useful part of the Angular SDK is the inclusion of the built in evaluation directives. These directives handle all the flag evaluation boilerplate for you, using Angular's directive abstractions which add functionality to elements. In its most basic form, the directive differentially renders templates based on the flag evaluation result:
<!-- evaluate a flag called new-message and show a render a different template based on the result -->
<div
*booleanFeatureFlag="'new-message'; default: true; else: booleanFeatureElse;">
<p>Welcome to this OpenFeature-enabled Angular app!</p>
</div>
<ng-template #booleanFeatureElse>
<p>Welcome to this Angular app.</p>
</ng-template>
String, Numeric, and Object flags are also supported. For these, you can supply templates based by matching against the returned flag value:
<!-- render this template if the value == 10 -->
<div
*numberFeatureFlag="'discountRate'; value: 10; default: 5; else: numberFeatureElse">
This is shown when the feature flag matches the specified discount rate.
</div>
<!-- render this template if the value != 10 -->
<ng-template #numberFeatureElse>
This is shown when the feature flag does not match the specified discount rate.
</ng-template>
Additionally, it's possible to bind the evaluation result and related metadata to the template by omitting the value
to match:
<!-- omitting the `value` to match against unconditionally renders this template -->
<div *stringFeatureFlag="'themeColor'; default: 'light'; let value;">
The theme color is {{ value }}.
</div>
You may want to hide some content until your provider is ready. For this reason, the directives support specifying templates to render before your provider is ready, and while it's reconciling its state after context changes. The directive will automatically re-render when the provider's readiness changes, or if the flag values themselves change.
<!-- render different templates based on the readiness of the flag provider -->
<div
*booleanFeatureFlag="'my-feature'; default: true; else: booleanFeatureElse; initializing: booleanFeatureInitializing; reconciling: booleanFeatureReconciling">
<p>This is shown when the feature flag is enabled.</p>
</div>
<ng-template #booleanFeatureElse>
<p>This is shown when the feature flag is disabled.</p>
</ng-template>
<ng-template #booleanFeatureInitializing>
<p>This is shown when the feature flag is initializing.</p>
</ng-template>
<ng-template #booleanFeatureReconciling>
<p>This is shown when the feature flag is reconciling.</p>
</ng-template>
As with other framework-specific SDKs, the Angular SDK is built on top of the existing @openfeature/web-sdk
.
Any OpenFeature provider built to support the web SDK can also be used with the @openfeature/angular-sdk
, no changes required.
We’re eager to expand the Angular SDK’s capabilities with future updates! If you're an Angular developer or interested in exploring how feature flags can enhance your applications, we encourage you to try out the OpenFeature Angular SDK. Happy coding! 🎉
]]>André discovered OpenFeature while researching the state of feature flag vendors. He became intrigued by OpenFeature's potential as a new standardization effort in the feature flag space and decided to contribute after noticing some "needs help" tags on GitHub issues.
For André, contributing to OpenFeature is more than just writing code—it's about solving critical software development and release challenges. He believes in the power of community-driven standards to reduce dependencies on third-party vendors, allowing companies to focus more on their products. The opportunity to shape these standards and libraries, and see them adopted by others, is incredibly rewarding for him.
André has made several significant contributions to OpenFeature, particularly in the .NET ecosystem. Some of his key achievements include:
For André, the most rewarding aspect of contributing to OpenFeature is seeing the library gain traction among developers. As more people start using OpenFeature, the responsibility to deliver high-quality outcomes increases, but so does the satisfaction of knowing his work is making a difference.
André’s advice for anyone looking to contribute to OpenFeature is simple: "Don't be afraid." The OpenFeature community is always welcoming new contributors, and André is particularly open to helping those interested in working on the .NET libraries.
We're grateful for André's dedication and contributions to the OpenFeature project. His work has made a significant impact, and we look forward to seeing how he continues to shape the future of feature flag standards.
]]>Methods on some key interfaces (such as provider resolvers) have been updated to indicate that they work asynchronously, by appending the Async
suffix in accordance with .NET conventions:
await Api.Instance.SetProvider(myProviderInstance);
await Api.Instance.SetProviderAsync(myProviderInstance);
Additionally, optional cancellation tokens can now be passed to applicable asynchronous methods. This allows for the cancellation of async tasks, and is consistent with .NET norms:
await client.GetBooleanValue("my-flag", false, context, options);
await client.GetBooleanValueAsync("my-flag", false, context, options, cancellationToken);
The return types for stages within hooks have been updated to take advantage of the performance benefit provided by ValueTasks.
The vast majority of hook stages run synchronously, and they are awaited internally by the SDK; so we can avoid the additional allocations associated with Tasks
by using ValueTasks
:
public class MyBeforeHook : Hook
{
public Task<EvaluationContext> Before<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null)
{
// code to run before flag evaluation
}
public ValueTask<EvaluationContext> BeforeAsync<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null, CancellationToken cancellationToken = default)
{
// code to run before flag evaluation
}
}
Generally, application authors won't have to make many changes.
As mentioned above, some async methods have been changed to conform to .NET conventions. Evaluation methods now have the "Async" suffix, and accept an optional cancellationToken:
await client.GetBooleanValue("my-flag", false, context, options);
await client.GetBooleanValueAsync("my-flag", false, context, options, cancellationToken);
The method for setting a provider has been updated similarly:
await Api.Instance.SetProvider(myProviderInstance);
await Api.Instance.SetProviderAsync(myProviderInstance);
Parameters previously named "client name" are now named "domain". "Domains" are a more powerful concept than "named clients", but in instances where named clients were previously used, function identically. No changes to consuming code are necessary these cases.
Provider authors must change their implementations in accordance with new methods names on the provider interface. Optionally, you can make use of the new cancellation token:
public override Task<ResolutionDetails<bool>> ResolveBooleanValue(
string flagKey,
bool defaultValue,
EvaluationContext? context = null)
{
// return boolean flag details
}
public override Task<ResolutionDetails<bool>> ResolveBooleanValueAsync(
string flagKey,
bool defaultValue,
EvaluationContext? context = null,
CancellationToken cancellationToken = default)
{
// return boolean flag details
}
It's no longer necessary to define, update or expose provider status.
If your provider requires initialization, simply define the optional InitializeAsync
method:
public class MyProvider : FeatureProvider
{
private ProviderStatus _status = ProviderStatus.NotReady;
public override ProviderStatus GetStatus()
{
return _status;
}
public override Task Initialize(EvaluationContext context)
public override Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default)
{
// some async initialization
}
}
For more details about this change, see our previous blog post.
Hooks must now return ValueTask
instead of Task
:
public class MyBeforeHook : Hook
{
public Task<EvaluationContext> Before<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null)
{
// code to run before flag evaluation
}
public ValueTask<EvaluationContext> BeforeAsync<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null, CancellationToken cancellationToken = default)
{
// code to run before flag evaluation
}
}
See here for the full changelog.
Thanks to all our users, and a special thanks to everyone who contributed to the .NET SDK:
The WeAreDevelopers World Congress is one of the largest developer conferences globally. It brings together tech enthusiasts, developers, engineers, and thought leaders from around the world to discuss the latest trends, innovations, and technologies shaping the future. With over 200 speakers, including industry pioneers and tech visionaries, the event offers a comprehensive agenda filled with keynote speeches, workshops, and networking opportunities. This congress is an excellent opportunity for learning, inspiration, and professional growth, making it a valuable event for anyone passionate about technology.
The GitHub Open Source Spotlight is a dedicated space within the WeAreDevelopers World Congress that highlights notable open-source projects and the communities behind them. This spotlight provides a platform for developers to showcase their work, share insights, and collaborate with peers. Being featured in this segment underscores the importance and impact of open-source contributions in the tech ecosystem. We are honored to be part of this lineup, where we can share our journey, innovations, and future plans with the broader tech community.
You can find us at Exhibition Hall 2.2. Our booth will feature:
Follow OpenFeature on all our social channels to stay updated throughout the event.
const multiProvider = new MultiProvider([
{
provider: new ProviderA(),
},
{
provider: new ProviderB(),
},
]);
await OpenFeature.setProviderAndWait(multiProvider);
openFeatureClient = OpenFeature.getClient();
const value = await openFeatureClient.getStringValue('flag-key', 'default value', someUser);
The Multi-Provider behaves like any other provider, but under the hood it combines results from any number of providers. It takes a list of providers as its only required parameter, then evaluates flags by progressing through the list of providers in order. By default, it will only evaluate the next provider if the current one indicates the flag was not found. Once there is a flag match, the Multi-Provider will return that result and not evaluate with the remaining providers.
In order to support diverse use cases, the Multi-Provider also accepts a Strategy parameter, which can be customized to control which providers are evaluated and how the final result is determined.
const multiProvider = new MultiProvider(
[
{
provider: new ProviderA(),
},
{
provider: new ProviderB(),
},
],
new SomeStrategy(),
);
The default Strategy is the FirstMatchStrategy
. This will evaluate providers in order, moving on to the next provider only if the current provider returns a FLAG_NOT_FOUND
result. If an error is thrown by any provider, the Multi-Provider will throw that error. The OpenFeature SDK will then catch the error and return the default value.
This strategy is useful for migrating from one provider to another, when some flags have been ported to the new system while others remain in the old one. By putting the new provider first in the provider's list, the Multi-Provider will prefer results from the new system but keep the old as a fallback.
FirstMatchStrategy
can also be used to pull feature flags from multiple sources, and return as soon as the flag is found.
FirstSuccessfulStrategy
is similar to FirstMatchStrategy
, except that errors from evaluated providers do not halt execution. Instead, it will return the first successful result from a provider. If no provider successfully responds, it will throw an error result.
One use case for this strategy is if you want the Multi-Provider to fallback to another provider in the case of an error, rather than throwing an error itself. For example, if an external vendor provider goes down, you may want to automatically fall back to a config file.
The ComparisonStrategy
requires that all providers agree on a value. If the providers return the same value, the result of the evaluation will be that value. Otherwise, the evaluation result will contain an error in the errors
field to indicate a mismatch, and the result value will be the value returned by the first provider. The ComparisonStrategy
also evaluates all providers in parallel, as it is not intended to exit as soon as it finds a match.
One use case for this strategy is validating the success of a provider migration. If the configuration in one provider has been recreated in another, this strategy confirms the flags and user targeting are consistent between those sources.
In order to support complex provider behaviour and diverse use cases, users can write custom strategies that extend the abstract BaseEvaluationStrategy
class. Some key methods to control the Multi-Provider’s behaviour include:
provider_a_
should only be evaluated using ProviderA, you can skip evaluating with any other providers when that prefix is used.export class MyCustomStrategy extends BaseEvaluationStrategy {
// In this example, we know keys containing 'provider_a_' will only exist in ProviderA
override shouldEvaluateThisProvider(
strategyContext: StrategyPerProviderContext,
evalContext: EvaluationContext,
): boolean {
if (strategyContext.flagKey.includes('provider_a_') && strategyContext.providerName !== 'ProviderA') {
return false;
}
return true;
}
}
determineFinalResult
. In parallel execution mode, this function is not called.
shouldEvaluateNextProvider
to continue to the next provider if that condition is met. For example, if your provider result should be skipped when flagMetadata.unusableResult
is true
, you can check for that property here.export class MyCustomStrategy extends BaseEvaluationStrategy {
override shouldEvaluateNextProvider<T extends FlagValue>(
strategyContext: StrategyPerProviderContext,
context: EvaluationContext,
details?: ResolutionDetails<T>,
thrownError?: unknown,
): boolean {
// if the provider indicates the result should not be used, continue to next provider
if (details?.flagMetadata.unusableResult === true) {
return true;
}
// otherwise, return this result
return false;
}
}
FinalResult
object, which includes the final resolution details and the corresponding provider, or an array of errors if the result was unsuccessful.
ComparisonStrategy
, you could override this function.export class MyCustomStrategy extends BaseEvaluationStrategy {
override runMode = 'parallel';
override determineFinalResult<T extends FlagValue>(
strategyContext: StrategyPerProviderContext,
context: EvaluationContext,
resolutions: ProviderResolutionResult<T>[],
): FinalResult<T> {
let value: T | undefined;
for (const resolution of resolutions) {
if (typeof value !== 'undefined' && value !== resolution.details.value) {
logger.warn('Mismatch between provider results: ', value, resolution.details.value);
} else {
value = resolution.details.value;
}
}
// we want to always use the first provider's resolution
const finalResolution = resolutions[0];
return this.resolutionToFinalResult(finalResolution);
}
}
Some key use cases supported by the Multi-Provider include:
Let’s say you were using one provider, OldProvider
, but have decided to switch to NewProvider
moving forward. You have been creating all new flags in NewProvider
, while slowly copying over your existing flags. This means your newest flags only exist in NewProvider
, some of your older flags only exist in OldProvider
, and an increasing number of flags exist in both. Previously, you would have to instantiate an OpenFeature client for each of your providers, or register the providers under different domains and manage switching between them manually. The Multi-Provider allows you to wrap both providers and prioritize the new one automatically:
const multiProvider = new MultiProvider([
{
provider: new NewProvider(),
},
{
provider: new OldProvider(),
},
]);
The NewProvider
now takes precedence and will always be used, unless a flag does not exist in its configuration. In that case, the Multi-Provider will fall back to OldProvider
automatically.
You can also use the Multi-Provider to confirm that two or more providers always agree on all evaluation results. For example, once you are finished migrating all of your feature flags from OldProvider
to NewProvider
, you may want to run concurrently for some time and track any instances where the evaluation results differ, to catch errors in the configuration of NewProvider
.
By using the ComparisonStrategy, you can configure the Multi-Provider to run all providers and return an error result if the results don’t match.
const newProvider = new NewProvider();
const oldProvider = new OldProvider();
const onMismatch = (_resolutions: ProviderResolutionResult<FlagValue>[]) => {
logger.warn('Provider mismatch!')
}
const multiProvider = new MultiProvider(
[
{
provider: newProvider,
},
{
provider: oldProvider,
}
],
new ComparisonStrategy(
oldProvider, // the fallback provider to trust in the case of a mismatch
onMismatch, // callback method called when provider resolutions don't match
)
)
The Multi-Provider can be used to combine feature flags from sources such as environment variables, database entries, and vendor feature flags, without having to instantiate multiple SDK clients. The order of the providers list establishes the precedence order of providers to control which should be trusted if keys exist in both systems. For example, if you want to use environment variables to override flag values from a vendor provider, you could pass the environment variable provider as the first in the providers list.
const multiProvider = new MultiProvider([
{
provider: new EnvVarProvider(),
},
{
provider: new VendorProvider(),
},
]);
await OpenFeature.setProviderAndWait(multiProvider);
openFeatureClient = OpenFeature.getClient();
const value = await openFeatureClient.getStringValue('flag-key', 'default value', someUser);
If the flag with the key ‘flag-key’ exists in both providers, it will only be evaluated with the EnvVarProvider
.
You can use the Multi-Provider to automatically fall back to a local configuration if an external vendor provider goes down, rather than using the default values. By using the FirstSuccessfulStrategy
, the Multi-Provider will move on to the next provider in the list if an error is thrown.
const multiProvider = new MultiProvider(
[
{
provider: new VendorProvider(),
},
{
provider: new EnvVarProvider(),
},
],
new FirstSuccessfulStrategy(),
);
In this example, if VendorProvider
is unavailable for any reason, EnvVarProvider
will be evaluated instead.
The Multi-Provider offers developers more flexibility and control when managing complex feature flag setups. As a first step, we have implemented it in the @openfeature/server-sdk and @openfeature/web-sdk.
We’re excited to get feedback about the current strategies and hear about other possible use cases. As we validate the Multi-Provider on the initial supported implementations we will gradually expand to support other languages and further strategies. We welcome contributors to bring this functionality to other languages.
]]>The OpenFeature client is a lightweight abstraction used to evaluate feature flags, implemented by every SDK.
Essentially, they represent a scope for feature flag evaluations.
React's context provider concept provides a means of sharing data and objects across multiple components without explicitly passing them through props.
A context provider is an ideal means of providing a bounded scope for flag evaluations by associating a react context with an OpenFeature client; the OpenFeature React SDK's OpenFeatureProvider
does exactly this.
Within the scope of this React provider, all flag evaluation hooks will make use of the bound OpenFeature client and its associated OpenFeature provider.
function App() {
return (
<OpenFeatureProvider>
{/* components in this scope share the same OpenFeature client and OpenFeature Provider */}
<MyPage/>
</OpenFeatureProvider>
);
}
The most fundamental feature of the React SDK is support for re-rending components using feature flags when the effective values of those flags change. Flag value changes could be the result of changes in the evaluation context which is the basis for flag evaluations rules, or change in the flag definitions themselves. Changes in the evaluation context are best exemplified by changes to user properties in an application; for example, a user logging in, adding something to their cart, or changing their subscriber level. Any of these examples could mean that we need to re-evaluate feature flags in light of this new information. The flag evaluation hooks provided by the React SDK do this automatically (by default) when the bound provider emits a PROVIDER_CONTEXT_CHANGED event.
function MyPage() {
// the "value" returned here is always up-to-date with changes in rules or contextual data
const { value: showNewMessage } = useFlag("new-message", false);
return (
<div>
<header>
{showNewMessage ? (
<p>Welcome to this OpenFeature-enabled React app!</p>
) : (
<p>Welcome to this React app.</p>
)}
</header>
</div>
);
}
Additionally, some feature flag solutions support realtime updates when flag configurations themselves are changed and the bound provider emits a PROVIDER_CONFIGURATION_CHANGED event. The React SDK also supports re-rendering in these cases so that a change in a flag definition immediately reflects those changes in the user interface. Both of these features can be disabled per-flag, or for the scope of the context provider.
React's suspense provides a powerful mechanism to simplify rendering when components require asynchronous data or have asynchronous side-effects. Without suspense, when a component makes an HTTP request or performs some other asynchronous operation, the developer must track the resolution of the corresponding promise, and display loading indicators (referred to by React as fallbacks) accordingly. React's Suspense paradigm uses some clever tricks to track this status for developers, and shows a specified fallback until the promise is resolved. Even more conveniently, within a suspense boundary, all promises are tracked as a group; when a new asynchronous call is added to any components in this scope, the developer need not make any changes to suspend rendering while this call is awaited!
Most feature flags solutions require some network I/O to retrieve their flag values or rules. Until this I/O is complete, we may want to suspend the UI to prevent users from seeing unexpected content or layout changes. The React SDK supports suspense while the provider is becoming ready, and while the provider is reconciling changes based on changes to the evaluation context. This means that you can easily show fallback elements until your feature flag provider is ready to evaluate flags.
{/* suspense boundary and fallback */}
<Suspense fallback={<Fallback />}>
<Greeting />
</Suspense>
function Fallback() {
return (<>Loading...</>);
}
function Greeting() {
// this hook will cause the component to suspend until the provider is ready
const { value: showEmoji } = useFlag("show-emoji", false);
return (
<>
{showEmoji ? (
<p>👋 Welcome to this React app!</p>
) : (
<p>Welcome to this React app!</p>
)}
</>
);
}
As previously mentioned, the React SDK is built on top of the existing @openfeature/web-sdk
.
Any OpenFeature provider built to support the web SDK can also be used with the @openfeature/react-sdk
, no changes required.
We have a few enhancements in mind, particularly around mutating evaluation context and an API that provides components (in addition to hooks), but we're excited to get feedback from the community on what we've built so far! If you're a React dev (or you're just looking for an excuse to familiarize yourself with the library) take the OpenFeature React SDK for a spin and let us know how it goes! You can play around with our test app here to familiarize yourself with some of the features.
]]>As pointed out by Pete Hodgson in his blog Feature Toggles (aka Feature Flags), feature flags have great utility, and they solve important problems for engineers every day, but the complexity introduced by widespread use of feature flags can be enormous. Every toggle point introduces a branch that must be tested, especially if it is enabled dynamically per-request in production. Testing every possible combination of feature flags is often impractical or impossible. To mitigate this issue, it is important to have robust and consistent monitoring.
Monitoring also goes beyond just identifying problems. Feature flags are often used for experimentation, A/B testing, canary releases, and other uses that require monitoring data in order to be effective. For example, if you wish to determine if your new spline reticulation algorithm is actually an improvement, you need to know the performance characteristics for both the new and the old algorithms. Just because the new algorithm is faster in your development environment does not mean it will be faster in production, where it may be run on different hardware or with unexpected inputs, or that it won’t have unexpected side-effects.
The key to effective monitoring is consistent monitoring, and this is where OpenTelemetry comes in. In the same way that OpenFeature brings consistency to feature flags, OpenTelemetry offers a consistent cross-language API for observability. This is helpful in many ways. First, it helps build an effective baseline so you can detect when something unexpected happens. Maybe your new spine reticulation algorithm is written in a new language that emphasizes memory safety. If the telemetry emitted by the new algorithm follows a different strategy from the old algorithm, it may be impossible to determine if it is actually an improvement. Second, it means if you change or upgrade tooling or vendors, your past telemetry data can be meaningfully compared with your new telemetry. Finally, in a heterogeneous environment with many different services, written in multiple languages and using different tooling, you can still draw meaningful insights from your telemetry data.
We can't do this without the support and input of our community. Whether you're an OpenFeature user, contributor, or interested for any other reason, head over to the OpenTelemetry Feature Flag Semantic Conventions project proposal and leave a comment or reaction to show your support. If you think you'd like to help contribute, leave a comment to that effect and we'll add you to the list.
]]>Folks have been asking for client-side support since the beginning of OpenFeature. Since web-based applications represent the vast majority of applications that people interact with on a daily basis, we are thrilled to provide teams with a consistent feature flagging experience across their entire stack. The Web SDK is a foundational SDK that can be used on its own but also lays the groundwork for framework-specific implementations. Having a vendor-neutral Web SDK provides an opportunity for a wide array of technologies everyone can use. The web framework ecosystem is massive and constantly evolving, it’s more important than ever to come together to ensure feature flagging is accessible to all.
At first glance, using a feature flag on the web may appear similar to server-side usage. In many cases, this is true! However, there are subtle, yet important differences. In OpenFeature, we have distilled these two different approaches down to static and dynamic context paradigms. The static context paradigm is commonly used on a client, and it’s the paradigm supported by the Web SDK. The rationale for introducing this paradigm can be found in our Catering to the client-side blog.
Feature flagging commonly leverages relevant contextual data like a user id, location, or browser type to enable powerful targeting capabilities. In OpenFeature, we refer to this as the evaluation context. On the web or mobile, the evaluation context typically remains constant for the duration of a user session; this is known as the static-context paradigm. This paradigm represents a simple, flexible, and powerful way of thinking about client-side feature flag evaluation. In particular, it was designed to support robust caching, with consideration for slow networks, and with high fault tolerance. This ensures minimal overhead and consistently fast feature flag evaluations.
It was of the utmost importance to ensure consistency across vendors and tools. While defining the static context paradigm in the OpenFeature specification, we identified opportunities to simplify provider development. One such example was making the providers stateless. This moves responsibility to the SDK instead of the provider author, making providers easier to develop and ensuring consistent behavior across implementations.
The Web SDK is great on its own but becomes even more powerful and user-friendly when leveraging framework-specific functionality. The React SDK is an excellent example of this. It abstracts the implementation details of supporting features like automatic component re-rendering and built-in suspense support. We plan to support many more frameworks, including Angular, Vue, and Svelte.
While this post is focused on the Web SDK, we haven’t forgotten about mobile. Our friends at Spotify recently donated an initial Kotlin and Swift SDK. These comprise the primary technologies in the mobile space, and in concert with the Web SDK, cover the majority of client platforms.
Finally, OpenFeature has been hard at work defining the OpenFeature Remote Evaluation Protocol (OFREP). This initiative aims to standardize how feature flags can be evaluated over a network, enabling seamless interoperability between tools and vendors that support the protocol.
OpenFeature is comprised of feature flag experts and enthusiasts. If you'd like to get involved, don't be shy! Join a community call, or join the #OpenFeature CNCF Slack channel, and help us build a great open standard that benefits the industry.
The Web SDK is available now. Give it a shot and let us know how it goes. We can’t wait to see what you build!
]]>We have a lot going on this week, and we'd love to meet you! Join a session, get your hands dirty at the Contribfest, and come see us at the booth! See below for details and links.
Speakers: Mike Beemer
Time: 10:10 CET, Tue, 19 Mar 2024
Location: Pavilion 7 | Level 7.1 | Room D
URL: https://sched.co/1aQWX
Whether for the purposes of legal compliance, marketing strategy, or simply because the entire solution is not yet ready, at some point you’ve probably had to write some crude code to manage the availability of a feature. Maybe this code enables a feature for a set of preview customers. Maybe it disables a feature in a jurisdiction with rigorous compliance laws. Though it has nothing to do with your problem domain, it’s still code that needs to be maintained, shipped, and tested. The good news is, a robust feature management solution combined with an observability platform can turn what was previously tech debt into an invaluable asset. Join us for an interactive session where we demonstrate the power of feature flags with OpenFeature. We’ll be doing some feature release improv with a real application, showing you how you can remove cruft, deploy with less risk, experiment safely in production, and use feature-flag telemetry to gain unique insights. Bring your phone. 😉
Speakers: Todd Baert
Track: SDLC
Time: 17:25, Wed, 20 Mar 2024
Location: Pavilion 7 | Level 7.3 | Paris Room
URL: https://sched.co/1YeT2
As software grows in size and complexity, rolling out new features in a highly distributed application, and understanding their impact, becomes an increasingly difficult task. OpenFeature and OpenTelemetry provide a set of vendor-agnostic and cloud-native APIs and SDKs for dynamic feature flag evaluation, and cloud-native observability. In this session, we walk through the process of instrumenting an application with OpenTelemetry, rolling out a new feature with OpenFeature, and leveraging OpenTelemetry for feature analytics. We will discuss the tradeoffs between traces, metrics, and the new events API, when each is appropriate, and how to make the same decision for your own application. We show that by using OpenTelemetry and OpenFeature together, you can easily understand the impact a feature has on your users' experience across cohorts, regions, and environments to make informed, data-driven decisions.
Speakers: Michael Beemer, Daniel Dyla
Track: SDLC
Time: 16:00 CET, Fri, 22 Mar 2024
Location: Pavilion 7 | Level 7.1 | Room A
URL: https://sched.co/1YeSC
Contribfest is an opportunity for contributors to help any way they'd like: implement an integration with a pet-project, create a provider that uses another CNCF service as a flag-management backend, implement a missing feature in an SDK or flagd, create a SDK for your favorite framework, or add an SBOM to one to one of the existing artifacts.
Facilitators: Todd Baert, Thomas Poignant, Lukas Reining
Time: 11:00 CET, Fri, 22 Mar 2024
Location: Pavilion 7 | Level 7.3 | W05
URL: https://sched.co/1YkTW
Find us at the booth in the Project Pavilion, Wednesday, Thursday, and Friday afternoon.
]]>There's no shortage of frameworks available when it comes to the development of enterprise software. Whether it's the "frontend" or "backend", developers are quick to avail things like React, Spring, Gin and Flask to avoid boilerplate code and structure their applications in a familiar way. Such frameworks also offer convenient abstractions that ease the employment of common patterns, think dependency injection as in Angular or Spring, or MVC as in Django or ASP.NET MVC. Many also provide extensibility features so that new functionality can be implemented seamlessly and idiomatically.
OpenFeature, we've been working on enhancing our specification and base SDKs to support the creation of such framework-level SDKs in order to bring vendor neutral feature flags to them. Specifically with respect to front end frameworks such as React, we've found that it was critical to refine the semantics of our events API and context-reconciliation concepts. This post discusses some of our improvements.
As discussed in previous blog posts, we've seen that client-side feature flag APIs share some commonalities we refer to collectively as the static-context paradigm; in short, the context used as the basis for flag evaluation is less frequently changed and generally corresponds to a user, or application state that a user occasionally modifies.
When a user logs in, or some state is modified, providers frequently need to fetch a new ruleset or re-evaluate their cache of flags based on the new contextual data.
We refer to this as reconciliation.
During reconciliation, some asynchronous work is often required (frequently this takes form of some kind of network request).
During this time, depending on the provider and the needs of the application, it might be necessary to display loading indicators, or prevent users from taking action.
Some frameworks have patterns or in-built functionality to support this, such as React's suspense.
In order to leverage such features, we've added a new RECONCILING
provider state and PROVIDER_RECONCILING
provider event.
These indicate the provider is in the process of reconciling it's internal state due to a context change.
Previously, something like this was achievable with the use of the STALE state and events, but we believed this was overloading the meaning of this state and didn't provide adequately robust semantics.
* transitions occurring when associated events are spontaneously emitted from the provider
Up to now, providers maintained a publicly-exposed representation of their own state: when they became ready, they changed their state to READY
; if they lost connection to their source of truth, they might change their state to STALE
or ERROR
and emit PROVIDER_STALE
or PROVIDER_ERROR
events.
This state management was burdensome for provider authors, and the addition of new states (such as RECONCILING
mentioned above) only worsened that issue.
Additionally, it allowed for widely divergent behavior between provider implementations, making the creation of framework-specific SDKs difficult and their behavior less predictable between providers, without meaningful benefit.
With this update, the provider interface has become stateless.
Now, the SDK itself maintains the provider's state based on the completion of lifecycle functions (initialization
, shutdown
, on context change
) and events emitted by the provider.
This simplifies things for provider authors, and results in a uniform experience for application authors, especially when leveraging framework-specific SDKs.
In some circumstances, providers may not be able to evaluate flags.
This could be because a provider hasn't yet been fully initialized, or has experienced some internal error.
Previously, provider-authors had to ensure their publicly exposed state was updated if such errors occurred, as well as emit an error event.
Furthermore, provider authors had to check with this state to accurately return an informative error code
(ie: PROVIDER_NOT_READY
) if evaluation was attempted in such states.
With these recent changes, we've added a new FATAL
error code, indicating that the provider has entered a irrecoverable error state (typically due to a bad credential, hostname or other value that's likely to represent a misconfiguration).
Along with this helpful new state, implementations will now "short-circuit" evaluations if the provider is in NOT_READY
or FATAL
states.
Overall, we believe these changes will improve consistency for application authors across providers, and simultaneously reduce the burden on provider authors as well.
If you're interested in contributing, there's no shortage of opportunities! You can create a client-side provider for a vendor or tool you're familiar with and host in our contrib repos. If the server-side is more your thing, you can help to update any of our existing server-side providers by simplifying them consistent with this latest spec change. As always, we're looking for help with our newest SDKs, some of which have yet to reach 1.0, including Kotlin, Swift, Python, Ruby, and Rust. We're also interested in more framework-specific SDKs as discussed in this earlier post. If there's a framework or library you think could benefit from an OpenFeature SDK, these are a great idea for a first contribution.
Thanks to everyone who worked on this specification change, and a special shout-out to the folks at Spotify who've been contributing to the spec, as well as to our client implementations including our Kotlin and Swift SDKs.
We're excited to be working on an open, vendor-neutral protocol for the evaluation of feature flags, which adheres to OpenFeature semantics. This protocol could be used as the basis for a single provider which is compatible with any implementing backend, and might be of particular usefulness for client-side feature flagging. If you'd like to know more, check out our dedicated slack channel for this topic.
]]>