Start Koin
Once you've declared your definitions in modules, you're ready to start the Koin container. This guide covers how to initialize Koin, configure it, and manage the container lifecycle.
The startKoin Function
startKoin is the main entry point to launch the Koin container. It registers the container in GlobalContext, making it accessible throughout your application.
Basic Startup
startKoin {
// Load modules
modules(coffeeAppModule)
}
Once started, Koin reads all modules and definitions, making them ready for dependency resolution via get() or by inject().
Complete Configuration
startKoin {
// Logging
logger(Level.INFO)
// Properties
environmentProperties()
fileProperties()
properties(mapOf("env" to "production"))
// Modules
modules(
coreModule,
networkModule,
dataModule
)
// Lazy modules (background loading)
lazyModules(analyticsModule, reportingModule)
// Create eager singletons
createEagerInstances()
// Override control
allowOverride(false)
}
Available Configuration Options
| Option | Description |
|---|---|
logger() | Set logging level and implementation |
modules() | Load modules immediately |
lazyModules() | Load modules in background (parallel) |
properties() | Load properties from map |
fileProperties() | Load from koin.properties file |
environmentProperties() | Load from system/environment |
createEagerInstances() | Create all createdAtStart singletons |
allowOverride() | Enable/disable definition overriding |
startKoin can only be called once. To load additional modules later, use loadKoinModules().
Multiplatform Configuration
Koin supports reusable configuration for Kotlin Multiplatform projects. Share common configuration across platforms while allowing platform-specific customization.
Shared Configuration Pattern
// Shared configuration function
fun initKoin(config: KoinAppDeclaration? = null) {
startKoin {
includes(config) // Platform-specific extensions
modules(sharedModule, dataModule, domainModule)
}
}
Platform-Specific Extensions
Android:
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
initKoin {
androidContext(this@MainApplication)
androidLogger()
}
}
}
iOS:
fun initKoinIos() {
initKoin {
logger(Level.DEBUG)
}
}
JVM:
fun main() {
initKoin {
printLogger()
fileProperties("/config/app.properties")
}
}
This pattern enables:
- Code reuse - Share core Koin setup across platforms
- Platform customization - Add platform-specific configuration
- Testability - Easy to configure for different test scenarios
Container Architecture
KoinApplication vs Koin
When you call startKoin, Koin creates two key objects:
KoinApplication- Configuration container- Holds modules, options, and settings
- Created during
startKoin - Produces the
Koininstance
Koin- Runtime container- Resolves dependencies
- Manages instances
- Used by
get()andinject()
startKoin {
modules(myModule)
} // Creates KoinApplication → produces Koin instance → registered in GlobalContext
GlobalContext
GlobalContext holds the Koin instance globally, making it accessible to KoinComponent classes:
val koin: Koin = GlobalContext.get() // Access the global Koin instance
This enables dependency injection throughout your app without passing the Koin instance explicitly.
Dynamic Module Management
Loading Modules After Startup
Load additional modules after startKoin using loadKoinModules():
// Initial startup
startKoin {
modules(coreModule)
}
// Later, load additional modules
loadKoinModules(featureModule, analyticsModule)
Use cases:
- SDK development - Libraries can load their modules without calling
startKoin - Feature modules - Load modules when features are enabled
- Dynamic plugins - Add modules at runtime
Unloading Modules
Remove modules and release their instances:
unloadKoinModules(featureModule, analyticsModule)
Important:
- Instances from unloaded modules are destroyed
- Definitions become unavailable
- Useful for feature toggling or memory management
Example: Feature Toggle
// Enable feature
if (isFeatureEnabled) {
loadKoinModules(premiumFeatureModule)
}
// Disable feature
if (!isFeatureEnabled) {
unloadKoinModules(premiumFeatureModule)
}
Stopping Koin
Close the Koin container and release all resources:
// Stop global Koin instance
stopKoin()
What happens:
- All singletons destroyed
- All scopes closed
onClosecallbacks invoked- Definitions cleared
- Cannot use
get()orinject()after stopping
For custom KoinApplication instances:
val koinApp = koinApplication {
modules(myModule)
}
// Later
koinApp.close()
Logging
Koin provides a simple logging API to track container activity (instance creation, resolution, etc.).
Log Levels
enum class Level {
DEBUG, // Detailed diagnostics
INFO, // General information
WARNING, // Warnings
ERROR, // Errors only
NONE // No logging
}
Available Loggers
| Logger | Platform | Description |
|---|---|---|
EmptyLogger | All | No logging (default) |
PrintLogger | All | Console output |
AndroidLogger | Android | Android Logcat |
SLF4JLogger | JVM | SLF4J integration |
Enable Logging
startKoin {
// Enable console logging at INFO level
logger(Level.INFO)
}
Android:
startKoin {
androidLogger(Level.DEBUG)
}
Custom Logger:
class CustomLogger : Logger() {
override fun display(level: Level, msg: MESSAGE) {
// Your logging implementation
println("[$level] $msg")
}
}
startKoin {
logger(CustomLogger())
}
What Gets Logged
- Module loading
- Definition registration
- Instance creation
- Dependency resolution
- Scope lifecycle
- Errors and warnings
Properties
Load configuration from multiple sources: environment variables, files, or code.
Loading Properties
From environment/system:
startKoin {
environmentProperties()
}
From file:
startKoin {
// Default: /src/main/resources/koin.properties
fileProperties()
// Custom file
fileProperties("/config/app.properties")
}
From code:
startKoin {
properties(mapOf(
"server_url" to "https://api.example.com",
"api_key" to "secret123",
"env" to "production"
))
}
Property File Format
Create /src/main/resources/koin.properties:
# Server configuration
server_url=https://api.example.com
server_port=8080
# Feature flags
feature_analytics=true
feature_premium=false
# API keys
api_key=secret123
Using Properties in Modules
module {
single {
ApiClient(
url = getProperty("server_url"),
port = getProperty("server_port", "8080") // With default
)
}
single {
AnalyticsService(
enabled = getProperty("feature_analytics", "false").toBoolean()
)
}
}
Property Priority
When properties are loaded from multiple sources, the last loaded wins:
startKoin {
fileProperties() // Loaded first
environmentProperties() // Overrides file properties
properties(mapOf(...)) // Overrides all previous
}
Accessing Properties from Components
class MyComponent : KoinComponent {
val serverUrl: String = getProperty("server_url")
val apiKey: String = getProperty("api_key", "default-key")
}
Feature Flags (4.1.0+)
Enable experimental Koin features via the options section:
startKoin {
options {
// Enable ViewModel scope factory (Android)
viewModelScopeFactory()
}
}
Check Koin release notes for available experimental features.
Best Practices
Startup
- Call
startKoinonce - At application entry point - Load critical modules immediately - Use
modules()for essential services - Use lazy modules - Defer non-critical modules with
lazyModules() - Enable logging in development - Use
logger(Level.DEBUG)for troubleshooting
Configuration
- Organize by environment - Use properties for environment-specific config
- Externalize secrets - Load API keys from environment, not code
- Use strict mode in production -
allowOverride(false)to catch errors early - Create eager instances sparingly - Only use
createdAtStartwhen necessary
Multiplatform
- Share common setup - Extract shared configuration to
initKoin()function - Platform-specific extensions - Use
includes()for platform customization - Consistent module organization - Keep module structure similar across platforms
Testing
- Stop Koin between tests - Call
stopKoin()to reset state - Use test modules - Override production modules with mocks
- Minimize global state - Consider
koinApplicationfor isolated tests
See Also
- Modules - Module organization and composition
- Definitions - Creating definitions
- Lazy Modules - Background module loading
- KoinComponent - Retrieving instances