FF4k

class FF4k(val featureStore: FeatureStore = InMemoryFeatureStore(), val propertyStore: PropertyStore = InMemoryPropertyStore(), val source: FF4k.Source = Source.KotlinApi, val autoCreate: Boolean = false)(source)

The primary entry point and facade for the FF4K feature flag library.

FF4K provides a coroutine-safe, Kotlin Multiplatform feature flag and configuration management system. This class serves as the main API for all feature flag operations, delegating storage concerns to pluggable FeatureStore and PropertyStore implementations.

Key Features

  • Feature Flags: Enable, disable, and check feature states with optional flipping strategies

  • Properties: Type-safe configuration properties with support for various data types

  • Groups: Organize features into logical groups for bulk operations

  • Auto-Create Mode: Automatically create missing features on first access

  • Flipping Strategies: Conditional feature activation based on runtime context

Architecture

FF4K follows a facade pattern, providing a unified API while delegating to:

  • FeatureStore: Manages feature flag persistence and retrieval

  • PropertyStore: Manages configuration property persistence and retrieval

Both stores default to in-memory implementations but can be replaced with persistent backends (Redis, databases, etc.) by implementing the respective interfaces.

Thread Safety

All operations are suspend functions designed for use with Kotlin coroutines. Internal state is protected using Mutex for coroutine-safe concurrent access. The stores themselves are responsible for their own thread-safety guarantees.

Context Resolution

When checking features with FlippingStrategy, context is resolved in priority order:

  1. Explicit FlippingExecutionContext passed to check

  2. Implicit context from withFlippingContext coroutine scope

  3. Empty context (when neither is provided)

Example Usage

Basic Feature Checking

val ff4k = FF4k()

// Add and check features
ff4k.addFeature("dark-mode", isEnabled = true)
if (ff4k.check("dark-mode")) {
enableDarkMode()
}

// Toggle features
ff4k.enable("beta-feature")
ff4k.disable("legacy-feature")

Using Flipping Strategies with Context

// Feature with percentage rollout strategy
val feature = Feature(
uid = "new-checkout",
isEnabled = true,
flippingStrategy = PercentageStrategy(mapOf("percentage" to "25"))
)
ff4k.addFeature(feature)

// Check with explicit context
val context = FlippingExecutionContext(ContextKeys.USER_ID to "user-123")
val isEnabled = ff4k.check("new-checkout", context)

// Or use coroutine context propagation
withFlippingContext(FlippingExecutionContext(ContextKeys.USER_ID to "user-123")) {
val isEnabled = ff4k.check("new-checkout") // context automatically available
}

Working with Groups

ff4k.addFeature(Feature("feature-a", isEnabled = false, group = "experiment-1"))
ff4k.addFeature(Feature("feature-b", isEnabled = false, group = "experiment-1"))

// Enable all features in a group at once
ff4k.enableGroup("experiment-1")

// Query features by group
val experimentFeatures = ff4k.featuresByGroup("experiment-1")

Auto-Create Mode

// With autoCreate enabled, missing features are created on first access
val ff4k = FF4k(autoCreate = true)

// This won't throw - creates a disabled feature automatically
val isEnabled = ff4k.check("non-existent-feature") // returns false

Configuration Properties

ff4k.addProperty(PropertyString("api.url", "https://api.example.com"))
ff4k.addProperty(PropertyInt("max.retries", 3))

val apiUrl: Property<String>? = ff4k.property("api.url")
val maxRetries: String? = ff4k.propertyAsString<Int>("max.retries")

See also

Constructors

Link copied to clipboard
constructor(featureStore: FeatureStore = InMemoryFeatureStore(), propertyStore: PropertyStore = InMemoryPropertyStore(), source: FF4k.Source = Source.KotlinApi, autoCreate: Boolean = false)

Types

Link copied to clipboard

Describes the origin or integration point from which this FF4k instance is accessed.

Properties

Link copied to clipboard

When true, automatically creates missing features as disabled on first access. When false, throws FeatureNotFoundException for missing features.

Link copied to clipboard

The store managing feature flag persistence. Defaults to InMemoryFeatureStore.

Link copied to clipboard

The store managing property persistence. Defaults to InMemoryPropertyStore.

Link copied to clipboard

Identifies the source/client type making API calls. Used for auditing and analytics.

Functions

Link copied to clipboard
suspend fun addFeature(feature: Feature): FF4k

Adds a feature to the store.

suspend fun addFeature(featureId: String, isEnabled: Boolean = false, description: String? = null): FF4k

Creates and adds a new feature to the store.

Link copied to clipboard
suspend fun <T> addProperty(property: Property<T>): FF4k

Adds a property to the store.

Link copied to clipboard
suspend fun check(featureId: String, executionContext: FlippingExecutionContext? = null): Boolean

Check if a feature is enabled.

Link copied to clipboard
suspend fun FF4k.checkAll(vararg featureIds: String, executionContext: FlippingExecutionContext? = null): Boolean

Check if all features in the list are enabled.

Link copied to clipboard
suspend fun FF4k.checkAny(vararg featureIds: String, executionContext: FlippingExecutionContext? = null): Boolean

Check if any feature in the list is enabled.

Link copied to clipboard
suspend fun containGroup(groupName: String): Boolean

Checks whether a group with the given name exists in the store.

Link copied to clipboard
suspend fun deleteFeature(feature: Feature): FF4k

Removes a feature from the store.

Link copied to clipboard
suspend fun <T> deleteProperty(property: Property<T>): FF4k

Removes a property from the store.

Link copied to clipboard
suspend fun disable(featureId: String): FF4k

Disables a feature flag.

Link copied to clipboard

Get all disabled features.

Link copied to clipboard
suspend fun disableGroup(groupName: String): FF4k

Disables all features belonging to a specific group.

Link copied to clipboard
suspend fun enable(featureId: String): FF4k

Enables a feature flag.

Link copied to clipboard

Get all enabled features.

Link copied to clipboard
suspend fun enableGroup(groupName: String): FF4k

Enables all features belonging to a specific group.

Link copied to clipboard
suspend fun feature(featureId: String): Feature

Retrieves a specific feature by its identifier.

Link copied to clipboard
suspend fun features(): Map<String, Feature>

Retrieves all features from the store.

Link copied to clipboard
suspend fun featuresByGroup(groupName: String): Map<String, Feature>

Retrieves all features belonging to a specific group.

Link copied to clipboard
suspend fun FF4k.featuresWithPermission(permission: String): List<Feature>

Get features with a specific permission.

Link copied to clipboard

Get features with a flipping strategy.

Link copied to clipboard
suspend fun hasFeature(featureId: String): Boolean

Checks whether a feature exists in the store.

Link copied to clipboard
suspend fun hasProperty(propertyId: String): Boolean

Checks whether a property exists in the store.

Link copied to clipboard
inline suspend fun <T> FF4k.ifEnabled(featureId: String, executionContext: FlippingExecutionContext? = null, block: () -> T): T?

Execute a block if the feature is enabled.

Link copied to clipboard
inline suspend fun <T> FF4k.ifEnabledOrElse(featureId: String, executionContext: FlippingExecutionContext? = null, enabled: () -> T, disabled: () -> T): T

Execute one block if the feature is enabled, another if disabled.

Link copied to clipboard
suspend fun properties(): Map<String, Property<*>>

Retrieves all properties from the store.

Link copied to clipboard
suspend fun <T> property(propertyId: String): Property<T>?

Retrieves a specific property by its identifier.

Link copied to clipboard
suspend fun <T> propertyAsString(propertyId: String): String?

Retrieves a property value as a string representation.

Link copied to clipboard
suspend fun FF4k.report(): String

Get a summary report of all features.

Link copied to clipboard
suspend fun FF4k.stats(): FeatureStats

Get statistics about features.

Link copied to clipboard
inline suspend fun FF4k.whenEnabled(featureId: String, executionContext: FlippingExecutionContext? = null, block: () -> Unit)

Execute a block with side effects if the feature is enabled.