Skip to main content
Version: 4.2

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

OptionDescription
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
info

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:

  1. KoinApplication - Configuration container

    • Holds modules, options, and settings
    • Created during startKoin
    • Produces the Koin instance
  2. Koin - Runtime container

    • Resolves dependencies
    • Manages instances
    • Used by get() and inject()
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
  • onClose callbacks invoked
  • Definitions cleared
  • Cannot use get() or inject() 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

LoggerPlatformDescription
EmptyLoggerAllNo logging (default)
PrintLoggerAllConsole output
AndroidLoggerAndroidAndroid Logcat
SLF4JLoggerJVMSLF4J 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

  1. Call startKoin once - At application entry point
  2. Load critical modules immediately - Use modules() for essential services
  3. Use lazy modules - Defer non-critical modules with lazyModules()
  4. Enable logging in development - Use logger(Level.DEBUG) for troubleshooting

Configuration

  1. Organize by environment - Use properties for environment-specific config
  2. Externalize secrets - Load API keys from environment, not code
  3. Use strict mode in production - allowOverride(false) to catch errors early
  4. Create eager instances sparingly - Only use createdAtStart when necessary

Multiplatform

  1. Share common setup - Extract shared configuration to initKoin() function
  2. Platform-specific extensions - Use includes() for platform customization
  3. Consistent module organization - Keep module structure similar across platforms

Testing

  1. Stop Koin between tests - Call stopKoin() to reset state
  2. Use test modules - Override production modules with mocks
  3. Minimize global state - Consider koinApplication for isolated tests

See Also