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
| Caracteristica | Koin | Dagger/Hilt |
|---|---|---|
| Tipo | Service locator/DI em runtime | DI em tempo de compilação |
| Linguagem | Kotlin-first | Java (com suporte Kotlin) |
| Validação | Runtime | Compilação |
| Configuração | DSL Kotlin | Anotações |
| Geracao de código | Nao | Sim (annotation processing) |
| Curva de aprendizado | Baixa | Moderada a alta |
| Google recomenda | Nao oficialmente | Sim (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
| Aspecto | Koin | Dagger/Hilt |
|---|---|---|
| Tempo de compilação | Sem impacto | Aumenta (annotation processing) |
| Startup da app | Ligeiramente mais lento | Mais rápido |
| Resolução de dependências | Runtime (reflexao) | Compilação (código gerado) |
| Uso de memória | Menor | Similar |
| Impacto em producao | Negligivel | Negligivel |
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.