AppConfig is a powerful, type-safe configuration management library for Kotlin Multiplatform that transforms how you handle app settings with zero boilerplate code. Define your configuration as simple interfaces and let KSP generate all the boring stuff.
// Android - SharedPreferences hell
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val isDarkMode = prefs.getBoolean("is_dark_mode_enabled", false)
prefs.edit().putBoolean("is_dark_mode_enabled", true).apply()
// iOS - NSUserDefaults pain
val userDefaults = NSUserDefaults.standardUserDefaults
val isDarkMode = userDefaults.boolForKey("is_dark_mode_enabled")
userDefaults.setBool(true, forKey = "is_dark_mode_enabled")
// expect/actual nightmare for every single property...
@Config(groupName = "UserSettings")
interface UserSettings {
@BooleanProperty(defaultValue = false, description = "Enable dark mode")
var isDarkModeEnabled: Boolean
@StringProperty(defaultValue = "https://api.example.com", description = "API endpoint")
var apiEndpoint: String
}
// Usage - pure magic β¨
val settings = AppConfig.usersettings
settings.isDarkModeEnabled = true // Automatically persisted!
less code. 100% type safety. Works everywhere.
- π― Zero Boilerplate: Define configurations with simple annotations
- π Type-Safe: Compile-time validation and type safety
- π True Multiplatform: Native support for Android (SharedPreferences) & iOS (NSUserDefaults)
- π¨ Auto-Generated Admin UI: Built-in configuration panel for debugging & A/B testing
- π± Platform-Specific Configs: Define Android-only or iOS-only settings
- β‘ KSP Powered: Compile-time code generation for zero runtime overhead
- ποΈ Perfect for A/B Testing: Type-safe feature flags and experiment groups
// build.gradle.kts
plugins {
id("com.google.devtools.ksp") version "CURRENT_KSP_VERSION"
id("io.github.mambawow.appconfig") version "0.0.3-alpha03"
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.mambawow.appconfig:appconfig-lib:0.0.3-alpha03")
// Optional: Admin UI panel
implementation("io.github.mambawow.appconfig:appconfig-panel:0.0.3-alpha03")
}
}
}
@Config(groupName = "UserSettings")
interface UserSettings {
@BooleanProperty(defaultValue = false, description = "Enable dark mode")
var isDarkModeEnabled: Boolean
@StringProperty(defaultValue = "https://api.example.com", description = "API base URL")
var apiEndpoint: String
@IntProperty(defaultValue = 30, description = "Network timeout in seconds")
var timeoutSeconds: Int
}
// Access your configuration anywhere in your app
val settings = AppConfig.usersettings
// Read values
println("Dark mode: ${settings.isDarkModeEnabled}")
println("API: ${settings.apiEndpoint}")
// Update values (automatically persisted across platforms!)
settings.isDarkModeEnabled = true
settings.timeoutSeconds = 60
@Composable
fun DebugScreen() {
ConfigPanel(
configItems = AppConfig.getAllConfigItems()
)
}
Perfect for QA teams to test different configurations without rebuilding the app!
Define configurations that only exist on specific platforms:
// androidMain/kotlin/.../AndroidSettings.kt
@Config
interface AndroidSettings {
@BooleanProperty(defaultValue = false, description = "Enable Camera X")
var isCameraXEnabled: Boolean
@BooleanProperty(defaultValue = true, description = "Use Material You colors")
var useMaterialYou: Boolean
}
// iosMain/kotlin/.../IOSSettings.kt
@Config
interface IOSSettings {
@BooleanProperty(defaultValue = true, description = "Enable haptic feedback")
var enableHaptics: Boolean
@BooleanProperty(defaultValue = false, description = "Use alternative app icons")
var useAlternateIcons: Boolean
}
AppConfig automatically detects the source set and generates code only for the target platform!
@Config
interface ExperimentConfig {
@OptionProperty(description = "Onboarding A/B test")
var onboardingGroup: OnboardingGroup
}
@Option
sealed class OnboardingGroup {
@OptionItem(0, "Group A - Tutorial", isDefault = true)
object Tutorial : OnboardingGroup()
@OptionItem(1, "Group B - Interactive demo")
object Demo : OnboardingGroup()
@OptionItem(2, "Group C - Skip onboarding")
object Skip : OnboardingGroup()
}
// Usage - type-safe and self-documenting
val experiment = AppConfig.experimentconfig
when (experiment.onboardingGroup) {
OnboardingGroup.Tutorial -> showTutorial()
OnboardingGroup.Demo -> showDemo()
OnboardingGroup.Skip -> skipOnboarding()
}
No more wondering what "variant_2" means six months later!
Annotation | Kotlin Type | Description | Use Case |
---|---|---|---|
@StringProperty |
String |
Text values | API URLs, user names |
@BooleanProperty |
Boolean |
True/false toggles | Feature flags, preferences |
@IntProperty |
Int |
32-bit integers | Timeouts, retry counts |
@LongProperty |
Long |
64-bit integers | Timestamps, large numbers |
@FloatProperty |
Float |
32-bit floating point | Animation speeds, ratios |
@DoubleProperty |
Double |
64-bit floating point | Precise calculations |
@OptionProperty |
Sealed Class |
Enum-like choices | A/B test groups, themes |
AppConfig uses Kotlin Symbol Processing (KSP) to generate all the boilerplate at compile time:
βββββββββββββββββββ KSP ββββββββββββββββββββ
β @Config β βββββββββ β Generated β
β Interface β β Implementation β
βββββββββββββββββββ ββββββββββββββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β Platform β ββββββββββββ ConfigStore β
β Storage β β Abstraction β
βββββββββββββββββββ ββββββββββββββββββββ
What gets generated:
- β Implementation classes with type-safe getters/setters
- β
Extension properties for easy access (
AppConfig.usersettings
) - β Platform-specific storage adapters (SharedPreferences/NSUserDefaults)
- β Configuration metadata for admin UIs
- β Bulk operations (reset, update from remote, etc.)
Module | Purpose | When to Use |
---|---|---|
appconfig-annotation |
Core annotations | Always (automatically included) |
appconfig-processor |
KSP processor | Always (automatically included) |
appconfig-lib |
Runtime library | Always |
appconfig-panel |
Admin UI | Optional (debugging, A/B testing) |
appconfig-gradle-plugin |
Build tools | Always (automatically applied) |
@Config
interface ShoppingConfig {
@BooleanProperty(defaultValue = false)
var enableOneClickCheckout: Boolean
@OptionProperty(description = "Checkout flow variant")
var checkoutVariant: CheckoutVariant
@IntProperty(defaultValue = 5)
var maxCartItems: Int
}
@Config
interface SocialConfig {
@BooleanProperty(defaultValue = true)
var enableStories: Boolean
@BooleanProperty(defaultValue = false)
var enableLiveStreaming: Boolean
@OptionProperty(description = "Feed algorithm")
var feedAlgorithm: FeedAlgorithm
}
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Kotlin Multiplatform
- Code generation powered by KSP
- UI components built with Compose Multiplatform
- π Remote configuration sync
- π Configuration encryption
- π Other platform support (Desktop, JS)