Koin vs Dagger/Hilt em 2026: qual framework de DI escolher?
A injecao de dependencia e um padrao fundamental em aplicacoes Kotlin bem arquitetadas. Koin e Dagger (com seu wrapper Hilt) sao as duas opcoes dominantes no ecossistema Android e Kotlin. Este artigo compara ambos os frameworks para ajudar voce a escolher o mais adequado para seu projeto.
Visao geral
| Caracteristica | Koin | Dagger/Hilt |
|---|---|---|
| Tipo | Service locator/DI em runtime | DI em tempo de compilacao |
| Linguagem | Kotlin-first | Java (com suporte Kotlin) |
| Validacao | Runtime | Compilacao |
| Configuracao | DSL Kotlin | Anotacoes |
| Geracao de codigo | Nao | Sim (annotation processing) |
| Curva de aprendizado | Baixa | Moderada a alta |
| Google recomenda | Nao oficialmente | Sim (Hilt) |
Configuracao 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() }
}
// Inicializacao
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() {
// ...
}
// Injecao em Composable
@Composable
fun TelaUsuarios(viewModel: UsuarioViewModel = koinViewModel()) {
// ...
}
Dagger/Hilt utiliza anotacoes e geracao de codigo:
// 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
}
// Inicializacao
@HiltAndroidApp
class MeuApp : Application()
// Uso no ViewModel
@HiltViewModel
class UsuarioViewModel @Inject constructor(
private val buscarUsuario: BuscarUsuarioUseCase,
private val service: UsuarioService
) : ViewModel() {
// ...
}
// Injecao em Composable
@Composable
fun TelaUsuarios(viewModel: UsuarioViewModel = hiltViewModel()) {
// ...
}
Koin requer menos codigo de configuracao e a DSL e mais intuitiva. Hilt requer mais boilerplate mas oferece validacao em tempo de compilacao.
Validacao de dependencias
Esta e uma das diferencas mais importantes. Dagger/Hilt valida todo o grafo de dependencias em tempo de compilacao. Se uma dependencia estiver faltando, o projeto nao compila. Isso previne erros de runtime.
Koin valida dependencias em runtime. Se uma dependencia nao estiver registrada, o erro so sera detectado quando a aplicacao tentar resolve-la. O Koin oferece a funcao checkModules para verificar o grafo em testes, mas nao e tao robusto quanto a validacao de compilacao 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 compilacao | Sem impacto | Aumenta (annotation processing) |
| Startup da app | Ligeiramente mais lento | Mais rapido |
| Resolucao de dependencias | Runtime (reflexao) | Compilacao (codigo gerado) |
| Uso de memoria | Menor | Similar |
| Impacto em producao | Negligivel | Negligivel |
Na pratica, a diferenca de performance entre ambos e negligivel para a maioria das aplicacoes. Dagger tem uma pequena vantagem teorica por resolver dependencias em tempo de compilacao, mas Koin e rapido o suficiente para aplicacoes de qualquer escala.
Testes
Koin facilita a substituicao de dependencias em testes:
@Test
fun testComMock() {
val mockRepository = mockk<UsuarioRepository>()
loadKoinModules(module {
single<UsuarioRepository> { mockRepository }
})
// teste com mock
}
Hilt tambem oferece suporte a testes com substituicao de dependencias:
@HiltAndroidTest
class UsuarioViewModelTest {
@BindValue
val mockRepository: UsuarioRepository = mockk()
@Test
fun testComMock() {
// teste com mock
}
}
Ambos os frameworks oferecem boa experiencia de testes. Koin e mais flexivel para substituir dependencias 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 dependencias entre Android, iOS, desktop e backend. Isso e uma vantagem significativa para projetos multiplataforma.
Dagger/Hilt e especifico 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 documentacao e clara. Um desenvolvedor pode aprender o basico em poucas horas.
Dagger/Hilt possui uma curva mais ingreme. Conceitos como Modules, Components, Scopes, Qualifiers e o fluxo de geracao de codigo 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 solucao de injecao de dependencia para Android. Isso significa que exemplos oficiais, codelabs e documentacao do Android utilizam Hilt. Essa recomendacao nao 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, aplicacoes Kotlin Multiplatform, equipes com desenvolvedores menos experientes em DI, prototipos e MVPs e projetos onde a DSL Kotlin e preferida a anotacoes.
Quando usar Dagger/Hilt
Hilt e ideal para projetos Android de grande escala, equipes que valorizam validacao em tempo de compilacao, projetos que seguem as recomendacoes oficiais do Google, aplicacoes com grafos de dependencia complexos e equipes com experiencia em Dagger.
Veredicto
Em 2026, ambos os frameworks sao opcoes solidas para injecao de dependencia em projetos Kotlin. Koin brilha pela simplicidade, pela DSL Kotlin idiomatica e pelo suporte a multiplataforma. Hilt se destaca pela validacao em tempo de compilacao, 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.