In a Gradle multi-project build, what is the difference in responsibility between settings.gradle.kts and build.gradle.kts?
answer
- one settings, one build-per-project
- Settings object vs Project object
- init phase vs configuration phase
- structure vs behaviour
- include/pluginManagement live in settings
basics
~10 ssettings.gradle.kts defines the build's structure — which projects exist (via include). build.gradle.kts defines what a single project does — its plugins, dependencies, and tasks.
solid answer
~40 sThere is exactly **one** `settings.gradle.kts` per build, evaluated first. It declares the structure: the root project name, which subprojects participate (`include(":app", ":lib")`), and build-wide setup like `pluginManagement` and `dependencyResolutionManagement`. It backs a `Settings` object. Each project (root and every subproject) gets its **own** `build.gradle.kts`, evaluated after settings during the configuration phase. It backs a `Project` object and declares per-project logic: which plugins to apply, dependencies, source sets, and task configuration. The mental split is *structure* (what projects exist, where, and how plugins/dependencies resolve) lives in settings; *behaviour* (what each project builds) lives in that project's build script. Settings runs once for the whole build; build scripts run once per project.
code
kotlin · 7 lines// settings.gradle.kts
rootProject.name = "shop"
include(":catalog", ":checkout")
// catalog/build.gradle.kts
plugins { `java-library` }
dependencies { api(project(":checkout")) }go deeper
State the basic split: settings = which projects exist; build = what one project does. Mention there's one settings file.
Add the backing objects (Settings vs Project) and the phase ordering (init then configuration), plus naming pluginManagement/dependencyResolutionManagement as settings concerns.
Explain why resolution rules must precede configuration, and contrast settings with root-build-script cross-cutting (subprojects/convention plugins).
Frame the split as a build-architecture boundary: structure/governance in settings, behaviour in per-project scripts, conventions in plugins — and how that keeps large builds maintainable.
## Two script kinds, two backing objects A Gradle build has **one settings script** and **one build script per project**. - `settings.gradle.kts` is backed by a `Settings` object. Gradle evaluates it **first**, during the *initialization phase*, to learn the build's shape — before any project is configured. - `build.gradle.kts` is backed by a `Project` object. Each participating project (the root and every included subproject) has its own build script, evaluated during the *configuration phase*. ## What belongs in settings The `Settings` object answers *what is this build made of?*: - `rootProject.name = "my-app"` — names the build. - `include(":core", ":web")` — declares which subprojects exist (hierarchical paths map to directories). - `pluginManagement { ... }` — where plugins resolve from and version constraints for them. - `dependencyResolutionManagement { ... }` — repositories for *dependencies* and version catalogs (`versionCatalogs { create("libs") { ... } }`). - `includeBuild("../shared")` — composite builds. These must be in settings because Gradle needs the structure and the plugin/dependency resolution rules *before* it can configure any project. ## What belongs in a build script The `Project` object answers *what does this one project build?*: - `plugins { ... }` — apply plugins to this project. - `dependencies { ... }` — this project's dependencies (using configurations like `implementation`, `api`). - `tasks.register(...)` / `tasks.named(...)` — define and configure tasks. - source set and extension configuration. ## Why the split matters Putting `include` in a build script, or `dependencies` in settings, is a category error — they target different objects and run in different phases. Settings is evaluated once per build; a build script is evaluated once per project. Cross-project conventions are usually applied from the **root** build script (e.g. `subprojects { ... }`) or, better, via convention plugins — not from settings. ```kotlin // settings.gradle.kts — structure only rootProject.name = "shop" pluginManagement { repositories { gradlePluginPortal() } } dependencyResolutionManagement { repositories { mavenCentral() } } include(":catalog", ":checkout") ```
- Which file is evaluated first, and why does that ordering matter?settings.gradle.kts, during the initialization phase. Gradle must know the project structure and plugin/dependency resolution rules before it can configure any project's build script.
- Can a build run without a settings file?A single-project build can run with just a build script (Gradle synthesises a default settings), but any multi-project build needs settings to declare the subprojects via include.
Settings is the table of contents and binding of a book (which chapters exist, in what order); each build.gradle.kts is an individual chapter's content.
saying these in an interview costs you the question
- Saying you put include or pluginManagement in build.gradle.kts.
- Claiming each project has its own settings file — there is exactly one per build.