Skip to main content
Version: 4.2

Annotations Reference

This page lists every Koin annotation, with its package, where it can be placed, its parameters, and one example. Each entry links to the page that explains the concept. To set up annotations, see Compiler Plugin Setup. To compare annotations with the DSL, see Choosing your style.

The annotations come from the io.insert-koin:koin-annotations artifact (same version as Koin). The Koin Compiler Plugin reads them at build time and generates the definitions. Most live in org.koin.core.annotation, Android-only ones in org.koin.android.annotation.

At a glance​

AnnotationPackageDeclares
@Singleton / @Singleorg.koin.core.annotationA single definition
@Factoryorg.koin.core.annotationA factory definition
@Scopedorg.koin.core.annotationA scoped definition
@KoinViewModelorg.koin.core.annotationA viewModel definition
@KoinWorkerorg.koin.android.annotationA WorkManager worker definition
@Scopeorg.koin.core.annotationThe scope a definition belongs to
@ViewModelScopeorg.koin.core.annotationA definition in the ViewModel scope
@ActivityScopeorg.koin.android.annotationA definition in the Activity scope
@ActivityRetainedScopeorg.koin.android.annotationA definition in the retained Activity scope
@FragmentScopeorg.koin.android.annotationA definition in the Fragment scope
@ScopeIdorg.koin.core.annotationA parameter resolved from a given scope
@Namedorg.koin.core.annotationA string qualifier
@Qualifierorg.koin.core.annotationA type or string qualifier
@InjectedParamorg.koin.core.annotationA parameter passed by the caller
@Propertyorg.koin.core.annotationA parameter read from a Koin property
@PropertyValueorg.koin.core.annotationA default value for a property
@Providedorg.koin.core.annotationA type provided outside the checked graph
@Moduleorg.koin.core.annotationA module class
@ComponentScanorg.koin.core.annotationPackages to scan for definitions
@Configurationorg.koin.core.annotationConfiguration labels for a module
@KoinApplicationorg.koin.core.annotationThe application entry point
@Monitororg.koin.core.annotationFunctions traced by the Kotzilla SDK

Definitions​

A definition annotation goes on a class (Koin calls its constructor) or on a function (Koin calls the function, top-level or inside a @Module class). Constructor and function parameters are resolved from the container. How each parameter type is resolved: Definitions.

When binds is empty, the definition is bound to its class and all its supertypes. List types in binds to bind only those.

@Singleton / @Single​

Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
bindsArray<KClass<*>>[]Types to bind. Empty binds all supertypes
createdAtStartBooleanfalseCreate the instance when Koin starts
@Singleton(binds = [UserRepository::class])
class UserRepositoryImpl(private val api: ApiService) : UserRepository

@Single and @Singleton are equivalent. One instance is kept for the lifetime of the container. Concept: Definitions.

@Factory​

Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
bindsArray<KClass<*>>[]Types to bind. Empty binds all supertypes
@Factory
class UserPresenter(private val repository: UserRepository)

A new instance is created for each request. Concept: Definitions.

@Scoped​

Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
bindsArray<KClass<*>>[]Types to bind. Empty binds all supertypes
@Scope(UserSession::class)
@Scoped
class SessionCache(private val repository: UserRepository)

One instance per scope, released when the scope closes. Use it with @Scope or a scope archetype (@ViewModelScope, @ActivityScope, ...). Concept: Scopes.

@KoinViewModel​

Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
bindsArray<KClass<*>>[]Types to bind. Empty binds all supertypes
@KoinViewModel
class UserViewModel(private val repository: UserRepository) : ViewModel()

Works on Android and Compose Multiplatform targets. Requires io.insert-koin:koin-core-viewmodel on the classpath (the build fails with KOIN-A001 otherwise). Concept: ViewModel.

note

With the Compiler Plugin, @KoinViewModel is in org.koin.core.annotation. The KSP processor used org.koin.android.annotation.KoinViewModel: update the import when you migrate (see Migrating from KSP).

@KoinWorker​

Package: org.koin.android.annotation (Android only). Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
bindsArray<KClass<*>>[]Types to bind
@KoinWorker
class SyncWorker(
context: Context,
params: WorkerParameters,
private val repository: UserRepository,
) : CoroutineWorker(context, params)

Requires io.insert-koin:koin-android-workmanager (the build fails with KOIN-A002 otherwise). Concept: WorkManager.

Scopes​

@Scope​

Target: CLASS, FUNCTION

ParameterTypeDefaultDescription
valueKClass<*>Unit::classScope type
nameString""Scope name, instead of a type
@Scope(UserSession::class)
class SessionCache(private val repository: UserRepository)

@Scope(name = "checkout")
class CheckoutState

Puts the definition in the given scope. On its own, @Scope declares a scoped definition. Add @Scoped, @Factory or @KoinViewModel to choose another kind or to set binds. Concept: Scopes.

@ViewModelScope​

Target: CLASS, FUNCTION. No parameters.

@ViewModelScope
class UserSessionCache(private val repository: UserRepository)

Declares a scoped definition in the scope of a ViewModel, created with the ViewModel and closed when it is cleared. Concept: Scopes.

@ActivityScope​

Package: org.koin.android.annotation (Android only). Target: CLASS, FUNCTION. No parameters.

@ActivityScope
class ScreenTracker(private val analytics: Analytics)

Declares a scoped definition in the Activity scope. The Activity must provide that scope (see Android Scopes).

@ActivityRetainedScope​

Package: org.koin.android.annotation (Android only). Target: CLASS, FUNCTION. No parameters.

@ActivityRetainedScope
class FormState

Declares a scoped definition in the retained Activity scope, which survives configuration changes. See Android Scopes.

@FragmentScope​

Package: org.koin.android.annotation (Android only). Target: CLASS, FUNCTION. No parameters.

@FragmentScope
class ListAdapterFactory

Declares a scoped definition in the Fragment scope. See Android Scopes.

@ScopeId​

Target: VALUE_PARAMETER

ParameterTypeDefaultDescription
valueKClass<*>Unit::classScope type. The scope ID is the class full name
nameString""Scope ID
@Factory
class ProfileService(@ScopeId(name = "user_session") val session: UserSession)

Resolves the parameter from the scope with that ID instead of the current scope (generated as getScope("user_session").get()). Compile-time safety does not check it, since the scope exists only at runtime. Concept: Scopes.

Qualifiers​

@Named​

Target: CLASS, FUNCTION, VALUE_PARAMETER

ParameterTypeDefaultDescription
valueString""String qualifier
typeKClass<*>Unit::classType qualifier. Use @Qualifier(Type::class) instead with the Compiler Plugin
@Singleton
@Named("local")
class LocalDatabase : Database

@Singleton
class UserRepository(@Named("local") private val database: Database)

The same string on the definition and on the parameter links them. jakarta.inject.Named and javax.inject.Named are read the same way. Concept: Qualifiers.

@Qualifier​

Target: CLASS, FUNCTION, VALUE_PARAMETER

ParameterTypeDefaultDescription
valueKClass<*>Unit::classType qualifier
nameString""String qualifier
@Singleton
@Qualifier(Remote::class)
class RemoteDataSource : DataSource

@Singleton
class UserRepository(@Qualifier(Remote::class) private val source: DataSource)

@Qualifier also marks your own qualifier annotations. Every annotation class annotated with @Qualifier or @Named (or jakarta.inject.Qualifier, javax.inject.Qualifier) becomes a qualifier:

@Qualifier
annotation class IoDispatcher

@Singleton
@IoDispatcher
fun ioDispatcher(): CoroutineDispatcher = Dispatchers.IO

A custom qualifier with no argument is a type qualifier on the annotation class. With a string or enum argument (@Dispatcher(AppDispatchers.IO)), the argument value is the qualifier. Concept: Qualifiers.

Parameters​

@InjectedParam​

Target: VALUE_PARAMETER. No parameters.

@Factory
class UserPresenter(@InjectedParam val userId: String, private val repository: UserRepository)

// caller
val presenter: UserPresenter = get { parametersOf("user-42") }

The value comes from parametersOf(...) at the call site, not from the container. Compile-time safety checks that call sites pass the right number and types of values (KOIN-D005, KOIN-D006). Concept: Injected Parameters.

@Property​

Target: VALUE_PARAMETER

ParameterTypeDefaultDescription
valueStringrequiredProperty key
@Factory
class ApiClient(@Property("api_url") val url: String)

Resolves the parameter with getProperty("api_url"). If a @PropertyValue with the same key exists, it is the fallback value. Without one, the build shows warning KOIN-P001 and the property must be set at startup. Concept: Properties.

@PropertyValue​

Target: FIELD

ParameterTypeDefaultDescription
valueStringrequiredProperty key
@PropertyValue("api_url")
val defaultApiUrl = "https://api.example.com"

@Factory
class ApiClient(@Property("api_url") val url: String)

Declares the default value used when the property is not set (generated as getProperty("api_url", defaultApiUrl)).

@Provided​

Target: CLASS, FUNCTION, VALUE_PARAMETER. No parameters.

@Singleton
class AnalyticsService(@Provided val firebase: FirebaseAnalytics)

Tells compile-time safety that the type is available at runtime without a declaration it can see (platform object, SDK, module loaded later). On a class, every use of the type is skipped. On a parameter, only that parameter. Runtime resolution is unchanged. Common Android types (Context, Activity, Fragment, SavedStateHandle, WorkerParameters, ...) don't need it. Concept: Compile-Time Safety.

Modules and application​

@Module​

Target: CLASS

ParameterTypeDefaultDescription
includesArray<KClass<*>>[]Other @Module classes to include
createdAtStartBooleanfalseCreate the module's single definitions when Koin starts
@Module(includes = [NetworkModule::class])
class DataModule {

@Singleton
fun database(context: Context): AppDatabase =
Room.databaseBuilder(context, AppDatabase::class.java, "app-db").build()
}

Groups definitions: annotated functions inside the class, plus annotated classes found by @ComponentScan. Concept: Modules.

@ComponentScan​

Target: CLASS, FIELD

ParameterTypeDefaultDescription
valuevararg StringemptyPackages to scan. Empty scans the package of the annotated class
@Module
@ComponentScan("com.myapp.data", "com.myapp.domain")
class AppModule

Adds to the module every annotated class and top-level function in the given packages and their subpackages, across Gradle modules. Concept: Modules.

note

The Compiler Plugin matches a package name and its subpackages. The glob patterns of the KSP processor (com.example.**, com.*.service) are not supported: list the packages instead.

@Configuration​

Target: CLASS, FIELD

ParameterTypeDefaultDescription
valuevararg StringemptyConfiguration labels. Empty means "default"
@Module
@ComponentScan
@Configuration
class CoreModule // label "default"

@Module
@Configuration("default", "test")
class FakeDataModule // labels "default" and "test"

A @KoinApplication loads every module that carries one of its configuration labels, including modules from other Gradle modules, without listing them. @Configuration("default") is the same as @Configuration. Concept: Modules.

@KoinApplication​

Target: CLASS

ParameterTypeDefaultDescription
configurationsArray<String>[]Configuration labels to load. Empty loads "default"
modulesArray<KClass<*>>[Unit::class] (none)@Module classes to load in addition
@KoinApplication(modules = [AppModule::class])
object MyApp

fun main() {
startKoin<MyApp> {
printLogger()
}
}

Marks the entry point. Start it with startKoin<MyApp>(), koinApplication<MyApp>() or koinConfiguration<MyApp>() (package org.koin.plugin.module.dsl). This is where compile-time safety checks the full graph. Modules from @Configuration load first, then the modules list in its order, so the explicit list wins on overrides. Concept: Starting Koin.

Monitoring​

@Monitor​

Target: CLASS, FUNCTION. No parameters.

@Monitor
class UserService(private val repository: UserRepository) {
fun findUser(id: String): User? = repository.findById(id)
}

The Compiler Plugin wraps the function body (or every public function of the class) with a Kotzilla SDK trace. It requires the Kotzilla SDK (io.kotzilla:kotzilla-core) on the classpath. Without it, the build shows warning KOIN-M001 and nothing is traced. Setup and data collected: Monitor.

JSR-330 annotations​

The Compiler Plugin also reads jakarta.inject and javax.inject annotations: @Singleton, @Named, @Inject and @Qualifier. See JSR-330.

Removed annotations​

@ExternalDefinition, @MetaDefinition, @MetaModule and @MetaApplication (package org.koin.meta.annotations) were generated by the KSP processor for its own use. The Compiler Plugin does not use them, and you never write them by hand.