What it is
Hilt is Android's recommended dependency injection framework, built on Dagger with a simplified API and Android lifecycle-aware components.
Annotate the Application with @HiltAndroidApp, provide dependencies in modules scoped to a component, and inject with @Inject or @HiltViewModel.
Installation
implementation("com.google.dagger:hilt-android:2.52")Getting started
The smallest useful thing you can do with it, and what each part means.
kotlin
@HiltAndroidApp
class MyApp : Application()
@Module
@InstallIn(SingletonComponent::class)
object DataModule {
@Provides @Singleton
fun provideDatabase(@ApplicationContext ctx: Context): AppDatabase =
Room.databaseBuilder(ctx, AppDatabase::class.java, "app.db").build()
@Provides
fun provideBookDao(db: AppDatabase): BookDao = db.bookDao()
}
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
abstract fun bindBookRepository(impl: RoomBookRepository): BookRepository
}
@HiltViewModel
class BookViewModel @Inject constructor(
private val repository: BookRepository,
) : ViewModel()Advanced usage
Where the library earns its place over a simpler alternative.
kotlin
@Qualifier @Retention(AnnotationRetention.BINARY)
annotation class AuthenticatedClient
@Provides @AuthenticatedClient
fun provideAuthClient(interceptor: AuthInterceptor): OkHttpClient = ...
class ApiService @Inject constructor(
@AuthenticatedClient private val client: OkHttpClient,
)
// Swap the whole module in instrumented tests.
@UninstallModules(DataModule::class)
@HiltAndroidTest
class BookRepositoryTest {
@get:Rule val hiltRule = HiltAndroidRule(this)
@Module @InstallIn(SingletonComponent::class)
object FakeDataModule {
@Provides fun provideDao(): BookDao = FakeBookDao()
}
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- cannot be provided without an @Inject constructor or @Provides
- The type is not in the graph. Add a @Provides or @Binds, or annotate its constructor.
- Build times increased sharply
- Annotation processing. Migrate from kapt to KSP, which is substantially faster.
Best practices
- Use @Binds rather than @Provides when simply mapping an interface to an implementation.
- Scope carefully — @Singleton on something holding an Activity context leaks it.
- Use qualifiers when two bindings share a type rather than wrapping one in a marker class.
- Choose Koin instead if build speed matters more than compile-time verification.
Background
Why it exists, and what it was reacting to.
Dagger is powerful and notoriously hard to set up on Android. Hilt provides the standard component hierarchy — application, activity, fragment, view model — so teams stop writing it themselves.
