Koin vs Dagger/Hilt em 2026: qual framework de DI escolher?

A injeção de dependência é um padrão fundamental em aplicações Kotlin bem arquitetadas. Koin e Dagger (com seu wrapper Hilt) são as duas opções dominantes no ecossistema Android e Kotlin. Este artigo compara ambos os frameworks para ajudar você a escolher o mais adequado para seu projeto.

Visao geral

CaracteristicaKoinDagger/Hilt
TipoService locator/DI em runtimeDI em tempo de compilação
LinguagemKotlin-firstJava (com suporte Kotlin)
ValidaçãoRuntimeCompilação
ConfiguraçãoDSL KotlinAnotações
Geracao de códigoNaoSim (annotation processing)
Curva de aprendizadoBaixaModerada a alta
Google recomendaNao oficialmenteSim (Hilt)

Configuração e setup

Koin utiliza uma DSL Kotlin intuitiva para definir modulos:

// Modulos Koin
val appModule = module {
    single<UsuarioRepository> { UsuarioRepositoryImpl(get()) }
    single<UsuarioService> { UsuarioServiceImpl(get()) }
    factory<BuscarUsuarioUseCase> { BuscarUsuarioUseCase(get()) }
    viewModel { UsuarioViewModel(get(), get()) }
}

val networkModule = module {
    single {
        Retrofit.Builder()
            .baseUrl("https://api.exemplo.com/")
            .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
            .build()
    }
    single<UsuarioApi> { get<Retrofit>().create() }
}

// Inicialização
class MeuApp : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            androidContext(this@MeuApp)
            modules(appModule, networkModule)
        }
    }
}

// Uso no ViewModel
class UsuarioViewModel(
    private val buscarUsuario: BuscarUsuarioUseCase,
    private val service: UsuarioService
) : ViewModel() {
    // ...
}

// Injeção em Composable
@Composable
fun TelaUsuarios(viewModel: UsuarioViewModel = koinViewModel()) {
    // ...
}

Dagger/Hilt utiliza anotações e geracao de código:

// Modulos Hilt
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit =
        Retrofit.Builder()
            .baseUrl("https://api.exemplo.com/")
            .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
            .build()

    @Provides
    @Singleton
    fun provideUsuarioApi(retrofit: Retrofit): UsuarioApi =
        retrofit.create(UsuarioApi::class.java)
}

@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
    @Binds
    @Singleton
    abstract fun bindUsuarioRepository(
        impl: UsuarioRepositoryImpl
    ): UsuarioRepository
}

// Inicialização
@HiltAndroidApp
class MeuApp : Application()

// Uso no ViewModel
@HiltViewModel
class UsuarioViewModel @Inject constructor(
    private val buscarUsuario: BuscarUsuarioUseCase,
    private val service: UsuarioService
) : ViewModel() {
    // ...
}

// Injeção em Composable
@Composable
fun TelaUsuarios(viewModel: UsuarioViewModel = hiltViewModel()) {
    // ...
}

Koin requer menos código de configuração e a DSL e mais intuitiva. Hilt requer mais boilerplate mas oferece válidação em tempo de compilação.

Validação de dependências

Esta e uma das diferenças mais importantes. Dagger/Hilt válida todo o grafo de dependências em tempo de compilação. Se uma dependência estiver faltando, o projeto não compila. Isso previne erros de runtime.

Koin válida dependências em runtime. Se uma dependência não estiver registrada, o erro só sera detectado quando a aplicação tentar resolve-la. O Koin oferece a função checkModules para verificar o grafo em testes, mas não e tao robusto quanto a válidação de compilação do Dagger.

// Verificacao de modulos Koin em testes
class VerificarModulosTest : KoinTest {
    @Test
    fun verificarTodosOsModulos() {
        koinApplication {
            modules(appModule, networkModule)
            checkModules()
        }
    }
}

Performance

AspectoKoinDagger/Hilt
Tempo de compilaçãoSem impactoAumenta (annotation processing)
Startup da appLigeiramente mais lentoMais rápido
Resolução de dependênciasRuntime (reflexao)Compilação (código gerado)
Uso de memóriaMenorSimilar
Impacto em producaoNegligivelNegligivel

Na prática, a diferenca de performance entre ambos e negligivel para a maioria das aplicações. Dagger tem uma pequena vantagem teorica por resolver dependências em tempo de compilação, mas Koin e rápido o suficiente para aplicações de qualquer escala.

Testes

Koin facilita a substituicao de dependências em testes:

@Test
fun testComMock() {
    val mockRepository = mockk<UsuarioRepository>()
    loadKoinModules(module {
        single<UsuarioRepository> { mockRepository }
    })
    // teste com mock
}

Hilt também oferece suporte a testes com substituicao de dependências:

@HiltAndroidTest
class UsuarioViewModelTest {
    @BindValue
    val mockRepository: UsuarioRepository = mockk()

    @Test
    fun testComMock() {
        // teste com mock
    }
}

Ambos os frameworks oferecem boa experiência de testes. Koin e mais flexivel para substituir dependências em tempo de teste, enquanto Hilt integra melhor com o framework de testes do Android.

Kotlin Multiplatform

Koin suporta Kotlin Multiplatform nativamente, permitindo compartilhar a definicao de dependências entre Android, iOS, desktop e backend. Isso e uma vantagem significativa para projetos multiplataforma.

Dagger/Hilt e específico para Android e JVM, sem suporte a Kotlin Multiplatform.

Curva de aprendizado

Koin possui uma curva de aprendizado significativamente mais baixa. A DSL Kotlin e intuitiva e a documentação e clara. Um desenvolvedor pode aprender o básico em poucas horas.

Dagger/Hilt possui uma curva mais ingreme. Conceitos como Modules, Components, Scopes, Qualifiers e o fluxo de geracao de código requerem estudo mais aprofundado. O Hilt simplifica bastante o uso do Dagger, mas ainda exige mais aprendizado que o Koin.

Recomendacao do Google

O Google recomenda oficialmente o Hilt como solução de injeção de dependência para Android. Isso significa que exemplos oficiais, codelabs e documentação do Android utilizam Hilt. Essa recomendacao não invalida o Koin, mas significa que seguir Hilt resulta em maior alinhamento com o ecossistema oficial.

Casos de uso recomendados

Quando usar Koin

Koin e ideal para projetos que priorizam simplicidade e velocidade de setup, aplicações Kotlin Multiplatform, equipes com desenvolvedores menos experientes em DI, protótipos e MVPs e projetos onde a DSL Kotlin e preferida a anotações.

Quando usar Dagger/Hilt

Hilt e ideal para projetos Android de grande escala, equipes que valorizam válidação em tempo de compilação, projetos que seguem as recomendações oficiais do Google, aplicações com grafos de dependência complexos e equipes com experiência em Dagger.

Veredicto

Em 2026, ambos os frameworks são opções solidas para injeção de dependência em projetos Kotlin. Koin brilha pela simplicidade, pela DSL Kotlin idiomatica e pelo suporte a multiplataforma. Hilt se destaca pela válidação em tempo de compilação, pela recomendacao oficial do Google e pela robustez em projetos de grande escala. Para a maioria dos projetos, a escolha e uma questao de preferencia da equipe. Para projetos multiplataforma, Koin e a escolha clara.