skip to content

settings.gradle.kts vs build.gradle.kts Roles

Why structural concerns live in settings.gradle.kts while per-project logic lives in each build.gradle.kts, and the different objects the two scripts configure. Interviewers ask because putting code in the wrong file is a frequent and confusing mistake.

on this pageshow

questions

5

In a Gradle multi-project build, what is the difference in responsibility between settings.gradle.kts and build.gradle.kts?

level: juniorimportance: must knowfreq 80%

answer

  1. one settings, one build-per-project
  2. Settings object vs Project object
  3. init phase vs configuration phase
  4. structure vs behaviour
  5. include/pluginManagement live in settings

basics

~10 s

settings.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 s

There 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
kotlin
// settings.gradle.kts
rootProject.name = "shop"
include(":catalog", ":checkout")

// catalog/build.gradle.kts
plugins { `java-library` }
dependencies { api(project(":checkout")) }

go deeper

for a junior

State the basic split: settings = which projects exist; build = what one project does. Mention there's one settings file.

for a middle

Add the backing objects (Settings vs Project) and the phase ordering (init then configuration), plus naming pluginManagement/dependencyResolutionManagement as settings concerns.

for a senior

Explain why resolution rules must precede configuration, and contrast settings with root-build-script cross-cutting (subprojects/convention plugins).

for a principal

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.

context

open as a page

Why do pluginManagement and dependencyResolutionManagement live in settings.gradle.kts rather than in a build script?

level: middleimportance: must knowfreq 60%

basics

~10 s

Gradle must know how to resolve plugins and dependencies before configuring any project. Settings is evaluated first, build-wide, so resolution rules and version catalogs belong there.

open as a page

How does Gradle locate and load settings.gradle.kts and each build.gradle.kts, and how does that affect the root project name?

level: middleimportance: should knowfreq 35%

basics

~10 s

Gradle searches upward from the current directory for settings.gradle(.kts) to find the build root. Each project loads build.gradle.kts from its projectDir. The root project name defaults to the root directory name.

open as a page

What are the Settings and Project objects in Gradle, and how do the settings and build scripts relate to them?

level: middleimportance: should knowfreq 55%

basics

~10 s

Each settings.gradle.kts is the body of a Settings object; each build.gradle.kts is the body of a Project object. Methods you call (include, dependencies) are members of those objects.

open as a page

A teammate puts shared subproject conventions (Java version, common dependencies) directly in settings.gradle.kts. Why is that wrong, and where should they go?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Settings can't configure projects — it only declares structure. Shared conventions belong in the root build script (subprojects/allprojects) or, better, in convention plugins applied per project.

open as a page