Initializing the Feature Client

The feature can be initialized in two different ways:

Using FeatureScope widget#

In most cases, you'll want to use this widget to initialize a feature client. The widget provides the instance of client created to all it's descendant widgets. In next step, we'll use FeatureBuilder which grabs the inherited client provided by FeatureScope.

In the starter app, open demo_app.dart. Then wrap the MaterialApp with FeatureScope.

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  Widget build(BuildContext context) {
    return FeatureScope<AssetFeatureProvider>(
      register: () => AssetFeatureProvider(),
      loader: (featureProvider) => featureProvider.load('assets/flags.json'),
      onLoaded: () => print('Flags Loaded'),
      child: MaterialApp(
        title: 'Feature Flags Demo',
        theme: ThemeData(useMaterial3: true),
        home: const LoginPage(),


The callback is used to pass instance of FeatureProvider to the scope.


It's used to load the feature provider asynchronously, where all the descendant FeatureBuilders will be waiting for the feature provider to load before evaluating values. In the code snippet above, we're using it to load asset from assets/flags.json using AssetFeatureProvider.


It can be used to perform any action after the feature provider completely loads.

Using OpenFeature class#

final featureProvider = AssetFeatureProvider();
OpenFeature.instance.provider = featureProvider;

final client = OpenFeature.instance.getClient();
await featureProvider.load('assets/flags.json');

The client can be used to resolve flags for any key. We'll discuss further about it in next step.