What is the difference between include and includeBuild in settings.gradle.kts?
answer
- include = subproject, one hierarchy
- includeBuild = composite/standalone build
- automatic dependency substitution
- build-logic convention plugins
- both in settings, init phase
basics
~10 sinclude adds a subproject to the current build (one shared build hierarchy). includeBuild wires in a separate, standalone Gradle build as a composite build, substituting its outputs for matching external dependencies.
solid answer
~40 sBoth are `Settings` API calls in `settings.gradle.kts`, but they operate at different levels. `include("core")` declares a **subproject** of the *current* build — it becomes part of the single project hierarchy rooted at `rootProject`, sharing one configuration pass and one task graph. `includeBuild("../shared-lib")` declares a **composite build**: it pulls in another *independent* Gradle build (with its own settings file and root project). Gradle automatically substitutes any external dependency whose group:module matches a project in the included build with that build's local output. This lets you develop a library and its consumer together without publishing to a repository. So: `include` = more modules inside one build; `includeBuild` = stitching separate builds together. Composite builds run included builds in their own context; included subprojects all live in the parent's context.
code
kotlin · 13 lines// settings.gradle.kts
rootProject.name = "app"
// Subproject of THIS build:
include("core")
// A separate standalone build, substituted for com.acme:shared-lib:*
includeBuild("../shared-lib")
// Local build that supplies convention plugins:
pluginManagement {
includeBuild("build-logic")
}go deeper
Know include adds a subproject; be aware includeBuild exists for separate builds.
Clearly contrast one-hierarchy subprojects vs. composite builds and mention automatic dependency substitution.
Discuss the build-logic / convention-plugin pattern and substitution semantics during resolution.
Weigh composite builds vs. monorepo subprojects for org-wide modularization, versioning, and CI boundaries.
## Two ways to compose Gradle distinguishes a **multi-project build** (one build, many subprojects) from a **composite build** (many builds stitched together). The two settings calls map to these. ## include — subprojects of one build ```kotlin // settings.gradle.kts rootProject.name = "app" include("core", "web") include(":web:api") // nested path ``` Each `include` produces a `Project` in the *same* hierarchy. There is one `rootProject`, one settings file, and during configuration all build scripts are evaluated into a single task graph. Subprojects reference each other with project dependencies: `implementation(project(":core"))`. ## includeBuild — composite (included) builds ```kotlin includeBuild("../shared-lib") ``` Here `../shared-lib` is a *complete, standalone* Gradle build with its own `settings.gradle.kts` and `rootProject`. Gradle treats it as an **included build**. Its key power is **dependency substitution**: if your build declares `implementation("com.acme:shared-lib:1.0")` and the included build produces a project with group `com.acme` and name `shared-lib`, Gradle automatically swaps the external coordinate for the local project output. No publishing required. ## When to use which - Use `include` for modules that are logically one product and version together. - Use `includeBuild` to develop separately-versioned/separately-released builds side by side, or to include build logic (the common `build-logic` convention-plugin pattern uses `includeBuild("build-logic")` or `pluginManagement { includeBuild(...) }`). ## Lifecycle notes Both calls happen during **initialization** while the `Settings` object is live. `includeBuild` causes additional, nested initialization for each included build (each evaluates its own settings). Substitution is resolved when dependencies are resolved later. You can also `includeBuild` inside `pluginManagement { }` to source plugins from a local build.
- What does includeBuild do automatically when a matching external dependency is declared?It performs dependency substitution — replacing the external group:module coordinate with the included build's local project output, so you don't need to publish.
- Why is includeBuild commonly used for a build-logic directory?It lets convention/precompiled plugins live in a separate composite build that the main build consumes via pluginManagement, keeping build logic versioned and testable separately.
- Can an included build have its own subprojects?Yes — an included build is a full build with its own settings.gradle.kts, so it can declare its own include() subprojects.
saying these in an interview costs you the question
- Saying include and includeBuild are interchangeable.
- Claiming includeBuild requires publishing the library to a repository first.
- Thinking includeBuild creates a subproject in the same hierarchy.