Skip to main content
Version: 4.1

Application, Configuration and Modules

Application Bootstrap with @KoinApplication

To create a complete Koin application bootstrap, you can use the @KoinApplication annotation on an entry point class. This annotation helps generate Koin application bootstrap functions:

@KoinApplication // load default configuration
object MyApp

@KoinApplication(
configurations = ["default", "production"],
modules = [MyModule::class]
)
object MyApp

This generates two functions for starting your Koin application:

// The import below gives you access to generated extension functions
import org.koin.ksp.generated.*

fun main() {
// Option 1: Start Koin directly
MyApp.startKoin()

// Option 2: Get KoinApplication instance
val koinApp = MyApp.koinApplication()
}

Both generated functions support custom configuration:

fun main() {
MyApp.startKoin {
printLogger()
// Add other Koin configuration
}

// Or with koinApplication
MyApp.koinApplication {
printLogger()
}
}

The @KoinApplication annotation supports:

  • configurations: Array of configuration names to scan and load
  • modules: Array of module classes to include directly (in addition to configurations)
info

When no configurations are specified, it automatically loads the "default" configuration.

Configuration Management with @Configuration

The @Configuration annotation allows you to organize modules into different configurations (environments, flavors, etc.). This is useful for organizing modules by deployment environment or feature sets.

Basic Configuration Usage

// Default configuration - these are equivalent
@Module
@Configuration
class CoreModule

@Module
@Configuration("default")
class CoreModule

Multiple Configuration Support

A module can be associated with multiple configurations:

// This module is available in both "prod" and "test" configurations
@Module
@Configuration("prod", "test")
class DatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}

// This module is available in default, test, and development
@Module
@Configuration("default", "test", "development")
class LoggingModule {
@Single
fun logger() = Logger()
}

Environment-Specific Configurations

// Development-only configuration
@Module
@Configuration("development")
class DevDatabaseModule {
@Single
fun database() = InMemoryDatabase()
}

// Production-only configuration
@Module
@Configuration("production")
class ProdDatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}

// Available in multiple environments
@Module
@Configuration("default", "production", "development")
class CoreModule {
@Single
fun logger() = Logger()
}

Using Configurations with @KoinApplication

Reference these configurations in your application bootstrap:

@KoinApplication(configurations = ["default", "production"])
class ProductionApp

@KoinApplication(configurations = ["default", "development"])
class DevelopmentApp

// Load only default configuration (same as @KoinApplication with no parameters)
@KoinApplication
class SimpleApp
info
  • Empty @Configuration is equivalent to @Configuration("default")
  • The "default" configuration is loaded automatically when no specific configurations are specified
  • Modules can belong to multiple configurations by listing them in the annotation

Default Module (Deprecated since 1.3.0)

danger

The default module approach is deprecated since Annotations 1.3.0. We recommend using explicit modules with @Module and @Configuration annotations for better organization and clarity.

While using definitions, you may need to organize them in modules or not. Previously, you could use the "default" generated module to host definitions without explicit modules.

If you don't want to specify any module, Koin provides a default one to host all your definitions. The defaultModule is ready to be used directly:

// The import below gives you access to generated extension functions
import org.koin.ksp.generated.*

fun main() {
startKoin {
defaultModule()
}
}

// or

fun main() {
startKoin {
modules(
defaultModule
)
}
}

Recommended approach: Instead of using the default module, organize your definitions in explicit modules:

@Module
@Configuration
class MyModule {
// Your definitions here
}

// Then use @KoinApplication
@KoinApplication
object MyApp
info

Don't forget to use the org.koin.ksp.generated.* import

Class Module with @Module

To declare a module, just tag a class with @Module annotation:

@Module
class MyModule

To load your module in Koin, just use the .module extension generated for any @Module class. Just create a new instance of your module MyModule().module:

// Use Koin Generation
import org.koin.ksp.generated.*

fun main() {
startKoin {
modules(
MyModule().module
)
}
}

Don't forget to use the org.koin.ksp.generated.* import

Components Scan with @ComponentScan

To scan and gather annotated components into a module, just use the @ComponentScan annotation on a module:

@Module
@ComponentScan
class MyModule

This will scan the current package and subpackages for annotated components. You can specify to scan a given package with @ComponentScan("com.my.package")

info

When using @ComponentScan annotation, KSP traverses across all Gradle modules for the same package. (since 1.4)

Definitions in Class Modules

To define a definition directly in your code, you can annotate a function with definition annotations:

// given 
// class MyComponent(val myDependency : MyDependency)

@Module
class MyModule {

@Single
fun myComponent(myDependency : MyDependency) = MyComponent(myDependency)
}

Note: @InjectedParam (for injected parameters from startKoin) and @Property (for property injection) are also usable on function members. See the definitions documentation for more details on these annotations.

Including Modules

To include other class modules in your module, use the includes attribute of the @Module annotation:

@Module
class ModuleA

@Module(includes = [ModuleA::class])
class ModuleB

This way you can just run your root module:

// Use Koin Generation
import org.koin.ksp.generated.*

fun main() {
startKoin {
modules(
// will load ModuleB & ModuleA
ModuleB().module
)
}
}