When would you choose a composite build (includeBuild) over a single multi-project build with include(...)?
answer
- one releasable unit -> multi-project
- independent products / separate repos -> composite
- composite substitutes published dep with local source
- composite = more config work, independent cadence
- default to multi-project, escalate to composite
basics
~20 sUse a single multi-project build when all modules live in one repo and release together. Use a composite build when you want to develop separate, independently-released builds (often different repos) together without publishing between changes.
solid answer
~50 sBoth let you build multiple things at once, but they answer different questions. A **multi-project build** is one build with many subprojects (`include(":app", ":lib")`) — they share a single settings file, configuration phase, and dependency graph, and they version and release as a unit. A **composite build** stitches together **independent builds**, each with its own settings file and release lifecycle, via `includeBuild`. Choose composite when the pieces are genuinely separate products that normally consume each other as **published binary dependencies**, but you occasionally want to develop them together — e.g., a library in repo A and its app in repo B. `includeBuild` transparently swaps the published dependency for the local source so you can iterate without publishing snapshots. If the modules always build and ship together, a plain multi-project build is simpler and faster (one configuration pass, shared classpath).
code
kotlin · 11 lines// MULTI-PROJECT: one build, ships together
// settings.gradle.kts
include(":app", ":lib")
// app/build.gradle.kts
dependencies { implementation(project(":lib")) }
// COMPOSITE: separate builds, independent cadence
// consumer/settings.gradle.kts
includeBuild("../my-library")
// app/build.gradle.kts
dependencies { implementation("com.example:my-library:1.0") } // local source while composedgo deeper
Recognize that multi-project = one build/one release; composite = separate builds composed together.
Articulate the independent-release-cadence and cross-repo-dev triggers for choosing composite.
Reason about configuration cost, dependency-coordinate substitution, and team workflow when deciding.
Set org guidance: default to multi-project; adopt composite to keep independently-versioned products developable together across repos without snapshot publishing.
## The decision The core question is: *do these modules form one releasable unit, or are they independent products that happen to depend on each other?* ### Multi-project build (`include`) - One `settings.gradle.kts`, one build, many projects. - Shared configuration phase and buildscript classpath. - Cross-project deps via `project(":lib")`. - Versioned and released **together**. - Simpler model, fastest because there is a single build lifecycle. ### Composite build (`includeBuild`) - Each piece is a **standalone build** with its own settings file and its own version/release cadence. - Composed only when you want to work across them locally. - Dependencies are normally consumed as **published artifacts** (`com.example:lib:1.0`); `includeBuild` substitutes local source for those coordinates while composed. - Lets two **separate repositories** be developed together without a publish step between edits. ## When composite wins 1. **Cross-repo local development** — the library and its consumer live in different repos and ship on different schedules, but right now you need to fix the library and verify the consumer in one go. 2. **Independent release cadence** — you do *not* want to force the library to re-version every time the app changes. 3. **Avoiding snapshot churn** — no more `publishToMavenLocal` + version bump loops while iterating. 4. **Aggregating unrelated builds** for a one-shot run. ## When multi-project wins 1. The modules are one product that always ships together. 2. You want the simplest, fastest configuration (one pass, shared model). 3. You rely heavily on cross-project task wiring that is more ergonomic within a single build. ## Cost of composite - Each included build configures independently → more configuration work than equivalent subprojects. - The mental model is heavier: many builds, each with its own settings, instead of one. ## Rule of thumb Start with a multi-project build. Reach for a composite build only when independent release lifecycles or separate repositories make the single-build model awkward.
- Why is a multi-project build usually faster to configure than the equivalent composite?A multi-project build has a single configuration phase and shared model; a composite configures each included build independently, repeating more work.
- If a library and app always release together, which would you pick?A single multi-project build — there is no independent cadence to justify the extra complexity of a composite.
saying these in an interview costs you the question
- Claiming composite builds are just a faster multi-project build — they add configuration overhead.
- Suggesting composite for modules that always ship together; that is what subprojects are for.