Skip to main content

Welcome to Anchor DI

Anchor DI is a compile-time dependency injection framework for Kotlin Multiplatform (KMP) with first-class support for Compose Multiplatform (CMP).

If you're building apps that run on Android, iOS, Desktop, and Web with shared Kotlin code — and you want clean, testable architecture — Anchor DI gives you a Hilt/Dagger-like experience that works everywhere. If it compiles, it works.


What is Kotlin Multiplatform (KMP)?​

Before diving into Anchor DI, let's understand the context. Kotlin Multiplatform lets you share business logic (networking, data layer, use cases) across Android, iOS, Desktop, and Web while keeping platform-specific UI and APIs where they belong. You write Kotlin once and run it everywhere — no JavaScript bridges, no duplicate codebases.

The challenge: dependency injection in KMP has been difficult. Most popular DI libraries either don't support KMP or have significant limitations. Anchor DI solves this.


Why Anchor DI?​

Dependency Injection in Kotlin Multiplatform is still a hard problem. Here's how existing solutions compare:

Existing SolutionLimitationWhy It Matters
KoinRuntime DI, ~5x slower startup, can fail at runtimeYour app might crash in production when a dependency is missing. Startup is slower because Koin builds the graph at launch.
Hilt / DaggerAndroid-onlyYou can't use them in shared KMP code; iOS and other platforms are left out.
Manual DIBoilerplate-heavy, error-proneYou write factory classes, pass dependencies through constructors manually — tedious and easy to get wrong.
Reflection-based DINot multiplatform-safeReflection is limited or unavailable on Kotlin/Native (iOS) and Kotlin/Wasm (Web).

Anchor DI solves this by shifting all DI logic to compile time:

  • No runtime reflection — Uses KSP (Kotlin Symbol Processing) to generate code at compile time
  • Fail fast — Missing bindings, circular dependencies, and scope violations fail the build — you find issues before your app runs
  • Multiplatform — Works in commonMain, androidMain, iosMain, jvmMain, wasmJsMain
  • Compose-first — Designed for Compose Multiplatform from day one with anchorInject() and viewModelAnchor()

A Quick Glimpse​

Here's what Anchor DI looks like in practice:

// 1. Define a repository with constructor injection
@Singleton
class UserRepository @Inject constructor(
private val api: UserApi
) {
suspend fun loadUser(id: String) = api.getUser(id)
}

// 2. In Compose, inject a ViewModel — dependencies are resolved automatically
@Composable
fun UserScreen(
viewModel: MainViewModel = viewModelAnchor()
) {
// ViewModel and UserRepository are created and wired up by Anchor DI
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
// ...
}

You declare what you need; Anchor DI figures out how to provide it. No manual factories, no boilerplate.


Design Principles​

Anchor DI is built on a few core principles:

  • Compile-time dependency graph — KSP analyzes your annotated code and generates factories and containers. No magic at runtime.
  • No Service Locator — Dependencies are declared explicitly (constructors, modules). No hidden globals.
  • No runtime reflection — Minimal runtime footprint; generated code does the work.
  • Strict validation — Missing bindings, cycles, scope violations — all fail the build. Predictable behavior.
  • Multiplatform by design — Same API on Android, iOS, Desktop, Web. Write once, run everywhere.

What's Next?​

Ready to get started? Here's the recommended path: