Skip to content

Feature flags

Read server-evaluated feature flags synchronously in Dart and Flutter, kept current over realtime.

await vb.flags.connect(context: {'plan': 'pro', 'country': 'IQ'});
if (vb.flags.isEnabled('new_checkout')) { ... }
vb.flags.getString('theme', 'light');
vb.flags.getNumber('max_uploads', 3);
vb.flags.getJson<Map<String, dynamic>>('layout', const {});
vb.flags.all; // every flag's value

connect fetches every flag the server evaluates for the context. Reads are synchronous from that cache and fall back to the default you pass when a flag is missing or has another type.

After connect, the flags are fetched again:

  • when an admin changes or deletes a flag (pushed over the realtime connection record subscriptions use; no second socket);
  • every 60 seconds, as a fallback (pollInterval:, at least 10 s, null for none);
  • after a sign-in or sign-out, since rules can target the user;
  • after the realtime connection comes back from a drop.
vb.flags.changes.listen((keys) => print('changed: $keys')); // Set<String>
await vb.flags.setContext({'plan': 'free'}); // fetches again
await vb.flags.refresh(); // now
vb.flags.disconnect(); // values stay readable

A failed fetch keeps the last values. connect(live: false) skips the realtime push.

The context is whatever the app sends, so a rule on plan is only as trustworthy as the app. The server fills auth from the session itself: rules on auth.* (the signed-in user) can be trusted. See Feature flags for writing rules.

In Flutter, rebuild on changes with a StreamBuilder over vb.flags.changes.