skip to content

What is the difference between include and includeBuild in settings.gradle.kts?

level: middleimportance: must knowfreq 60%

answer

  1. include = subproject, one hierarchy
  2. includeBuild = composite/standalone build
  3. automatic dependency substitution
  4. build-logic convention plugins
  5. both in settings, init phase

basics

~10 s

include 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 s

Both 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
kotlin
// 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

for a junior

Know include adds a subproject; be aware includeBuild exists for separate builds.

for a middle

Clearly contrast one-hierarchy subprojects vs. composite builds and mention automatic dependency substitution.

for a senior

Discuss the build-logic / convention-plugin pattern and substitution semantics during resolution.

for a principal

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.

context