A project with multiple Gradle modules is known as a multi-module project. This
guide encompasses best practices and recommended patterns for developing
multi-module Android apps.
| **Note:** This page assumes a basic familiarity with the [recommended app
| architecture](https://developer.android.com/topic/architecture).

## The growing codebase problem

In an ever-growing codebase, scalability, readability, and overall code quality
often decrease through time. This comes as a result of the codebase increasing
in size without its maintainers taking active measures to enforce a structure
that is easily maintainable. Modularization is a means of structuring your
codebase in a way that improves maintainability and helps avoid these problems.

## What is modularization?

Modularization is a practice of organizing a codebase into loosely coupled and
self contained parts. Each part is a module. Each module is independent and
serves a clear purpose. By dividing a problem into smaller and easier to solve
subproblems, you reduce the complexity of designing and maintaining a large
system.
![](https://developer.android.com/static/topic/modularization/images/1_sample_dep_graph.png) **Figure 1**: Dependency graph of a sample multi-module codebase

## Benefits of modularization

The benefits of modularization are many, though they each center upon improving
the maintainability and overall quality of a codebase. The following table
summarizes the key benefits.

| Benefit | Summary |
|---|---|
| Reusability | Modularization enables opportunities for code sharing and building multiple apps from the same foundation. Modules are effectively building blocks. Apps should be a sum of their features where the features are organized as separate modules. The functionality that a certain module provides may or may not be enabled in a particular app. For example, a `:feature:news` can be a part of the full version flavor and wear app but not part of the demo version flavor. |
| Strict visibility control | Modules enable you to easily control what you expose to other parts of your codebase. You can mark everything but your public interface as `internal` or `private` to prevent it from being used outside the module. |
| Customizable delivery | [Play Feature Delivery](https://developer.android.com/guide/playcore/feature-delivery) uses the advanced capabilities of app bundles, allowing you to deliver certain features of your app conditionally or on demand. |

The benefits of modularization are only achievable with a modularized codebase.
The following benefits might be achieved with other techniques but
modularization can help you enforce them even more.

| Benefit | Summary |
|---|---|
| Scalability | In a tightly coupled codebase a single change can trigger a cascade of alterations in seemingly unrelated parts of code. A properly modularized project will embrace the [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) principle and therefore limit the coupling. This empowers the contributors through greater autonomy. |
| Ownership | In addition to enabling autonomy, modules can also be used to enforce accountability. A module can have a dedicated owner who is responsible for maintaining the code, fixing bugs, adding tests, and reviewing changes. |
| Encapsulation | Encapsulation means that each part of your code should have the smallest possible amount of knowledge about other parts. Isolated code is easier to read and understand. |
| Testability | Testability characterizes how easy it is to [test](https://developer.android.com/training/testing) your code. A testable codebase is one where components can be easily tested in isolation. |
| Build time | Some Gradle functionalities such as incremental build, build cache or parallel build, can leverage modularity to [improve build performance](https://developer.android.com/studio/build/optimize-your-build). |

## Common pitfalls

The granularity of your codebase is the extent to which it is composed of
modules. A more granular codebase has more, smaller modules. When designing a
modularized codebase, you should decide on a level of granularity. To do so,
take into account the size of your codebase and its relative complexity. Going
too fine-grained will make the overhead a burden, and going too coarse will
lessen the benefits of modularization.

Some common pitfalls are as follows:

- **Too fine-grained** : Every module brings a certain amount of overhead in the form of increased build complexity and [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code). A complex build configuration makes it difficult to [keep configurations consistent](https://developer.android.com/topic/modularization/patterns#consistent-configuration) across modules. Too much boilerplate code results in a cumbersome codebase that is difficult to maintain. If overhead counteracts scalability improvements, you should consider consolidating some modules.
- **Too coarse-grained**: Conversely, if your modules are growing too large you might end up with yet another monolith and miss the benefits that modularity has to offer. For example, in a small project it's ok to put the data layer inside a single module. But as it grows, it might be necessary to separate repositories and data sources into standalone modules.
- **Too complex**: It doesn't always make sense to modularize your project. A dominating factor is the size of the codebase. If you don't expect your project to grow beyond a certain threshold, the scalability and build time gains won't apply.

## Is modularization the right technique for me?

If you need the benefits of reusability, strict visibility control or to use the
[Play Feature Delivery](https://developer.android.com/guide/playcore/feature-delivery), then modularization is a necessity for you. If you
don't, but still want to benefit from improved scalability, ownership,
encapsulation, or build times, then modularization is something worth
considering.

## Samples

- [Now in Android](https://github.com/android/nowinandroid) - fully functional Android app featuring modularization.
- [Multi module architecture sample](https://github.com/android/architecture-samples/tree/multimodule)