Flagward

OpenFeature

@flagward/openfeature-web — an OpenFeature provider for the browser.

OpenFeature is the CNCF standard API for feature flags. @flagward/openfeature-web is a provider for its web SDK: an application that already evaluates flags through OpenFeature switches to Flagward by changing the provider, and nothing else.

If your application does not use OpenFeature, the Flagward adapter for your framework is the simpler choice.

This provider is for the browser (@openfeature/web-sdk). A server provider for @openfeature/server-sdk is not available yet.

Installation

npm install @openfeature/web-sdk @flagward/openfeature-web

@flagward/core comes with the provider — you do not install it separately.

Quick start

import { OpenFeature } from '@openfeature/web-sdk';
import { FlagwardWebProvider } from '@flagward/openfeature-web';

await OpenFeature.setContext({ targetingKey: user.id, country: user.country });
await OpenFeature.setProviderAndWait(
  new FlagwardWebProvider({
    apiKey: 'your-environment-api-key',
    host: 'https://flags.example.com',
  }),
);

const client = OpenFeature.getClient();

if (client.getBooleanValue('new-checkout', false)) {
  renderNewCheckout();
}

The options are the same as the core client's: apiKey, host, timeout and logLevel. host defaults to the hosted service at https://app.flagward.com.

Coming from another provider, the change is the provider itself:

- OpenFeature.setProvider(new SomeOtherProvider(...));
+ OpenFeature.setProvider(new FlagwardWebProvider({ apiKey }));

The evaluation context

Flagward rules read the context OpenFeature holds:

  • targetingKey becomes user_id, the identity percentage rollouts and variant splits bucket by. A user_id attribute is used only when there is no targeting key.
  • Every other attribute is a trait under its own name: country in the context is what a country EQUALS US rule reads.

Changing the context with OpenFeature.setContext needs nothing from the server — the next evaluation uses it.

Flag types

OpenFeature callFlagward flagValue
getBooleanValueBOOLEANthe flag's result
getBooleanValueMULTIVARIATEwhether the flag is enabled
getStringValueMULTIVARIATEthe variant's name
getStringValueBOOLEANyour default, with TYPE_MISMATCH
getNumberValue, getObjectValueanyyour default, with TYPE_MISMATCH

A key the environment does not have answers with your default and FLAG_NOT_FOUND.

Reasons

getBooleanDetails and getStringDetails say why a value was chosen:

ReasonWhen
TARGETING_MATCHa rule matched and decided the value
SPLITthe user's hash bucket picked the variant
DEFAULTnothing targeted the user: no rule matched, or there is no targeting key to split by (the control variant)
STATICthe value does not depend on the user: an override, or an enabled flag with nothing to target
DISABLEDthe flag is off
client.getStringDetails('checkout-flow', 'control');
// { value: 'treatment', variant: 'treatment', reason: 'SPLIT', ... }

Live updates

When a flag changes in the dashboard, the provider emits ConfigurationChanged:

import { ProviderEvents } from '@openfeature/web-sdk';

client.addHandler(ProviderEvents.ConfigurationChanged, () => rerender());

If the flags cannot be loaded — a wrong API key, an unreachable host — setProviderAndWait rejects, the provider is in the ERROR state, and every evaluation answers with its default.

Frameworks

OpenFeature's own SDKs build on this provider:

  • React: @openfeature/react-sdk
  • Angular: @openfeature/angular-sdk

Vue, Solid and Svelte have no OpenFeature SDK. There you use @openfeature/web-sdk directly, or the Flagward adapter for the framework.

Pick one entry point per application. The provider and a Flagward adapter each create their own client, so using both means two connections and two caches that can briefly disagree.

Registration

The provider registers with the server as OPENFEATURE_WEB.

On this page