Evaluate feature flags
Read feature flags and variants for the current person, with safe defaults.
Feature flags turn features on or off, or pick a variant, for each person without a new build. Voidhash evaluates flags for the current person; you create them and set rollouts in Studio. See Feature flags.
Feature flags are in early access. Ask us on Discord, or email support@voidhash.com on a paid plan, to turn them on for your team.
A build that uses a test key gets each flag's test configuration, which is the same as production's until you change it in Studio. See Environments.
Evaluate flags
Pass the keys you need, or an empty list to evaluate every flag:
val flags = voidhash.getFeatureFlags(listOf("new_onboarding", "pricing_test"))
val newOnboarding = flags.firstOrNull { it.key == "new_onboarding" }?.enabled == true
val pricingVariant = flags.firstOrNull { it.key == "pricing_test" }?.variantKeyEach FeatureFlag has a key, enabled, the selected variantKey, and the variant's payload. A
disabled flag has no variant. Payloads are untyped JSON: a JSONObject, JSONArray, String,
Number, Boolean, or null. Validate one before you use it:
import org.json.JSONObject
val copy = flags.firstOrNull { it.key == "onboarding_copy" }?.payload as? JSONObject
val headline = copy?.optString("headline")?.takeIf { it.isNotEmpty() } ?: "Welcome"Results are cached per person, fresh for 5 minutes and served after that while a refresh runs, so
they work offline. getFeatureFlagsState adds isStale and isExpired.
Defaults and updates
With nothing cached, a flag read waits at most 2 seconds, then answers without an evaluation while
the request continues. Set a default for each flag that needs a value before then, read flags
synchronously with isFeatureEnabled, and collect featureFlags to update your UI when an
evaluation arrives:
import com.voidhash.sdk.FeatureFlagOptions
import com.voidhash.sdk.Voidhash
import com.voidhash.sdk.VoidhashOptions
val voidhash = Voidhash.configure(
context = this,
publishableKey = "vh_pk_...",
options = VoidhashOptions(
featureFlags = FeatureFlagOptions(
maxWaitMs = 2_000,
defaults = mapOf("new_onboarding" to false),
),
),
)
lifecycleScope.launch {
voidhash.featureFlags.collect {
showNewOnboarding(voidhash.isFeatureEnabled("new_onboarding"))
}
}isFeatureEnabled reads the latest evaluation from memory and never suspends. A flag without an
evaluated value reads as its default, or as disabled. getFeatureFlags includes the default of
each requested key that has no evaluated value, as a flag without a variant. featureFlags is a
StateFlow<List<FeatureFlag>>.
Choose defaults that are safe while flags load or stay unavailable. Don't gate paid access on a flag; use perks.
Identity changes
When an anonymous person signs in, their flags keep answering until the identified person's evaluation arrives, so an offline sign-in doesn't turn features off. Identifying can move a person into a different rollout bucket. Signing out or switching accounts clears the cached flags, so one person never sees another's assignment.
Next steps
- Feature flags in Studio: rollouts, variants and targeting.
- A/B tests on paywalls, which need no flag code.
- Identify users.
Something wrong or missing on this page? Tell us by email or on Discord.