MΓ³dulo 16 Β· Modularize by Feature β LecciΓ³n 2 de 4 Β· ~6 min
api vs implementation
Two ways to declare a module dependency
Splitting into modules only pays off if changing one module doesn't force every other module to recompile too. That's what Gradle's two dependency configurations control:
implementation(project(...))β the dependency is used internally but hidden from anything that depends on you. If:feature:bookingsusesimplementation(project(":core:network")), then:app(which depends on:feature:bookings) has no idea:core:networkeven exists β and can't accidentally reach into it.api(project(...))β the dependency leaks through. Anything that depends on you can also see and use it directly, transitively.
Default to implementation. It gives Gradle a smaller, more precise picture of what actually needs rebuilding when something changes β change :core:network and only the modules that implementation-depend on it (plus anything whose public API changed) need to recompile, not every module transitively downstream. Reach for api only when a type from that dependency appears in your own module's public function signatures β otherwise everyone downstream pays for a dependency they never asked for.