skip to content

What is a Settings plugin in Gradle, and how does it differ from a Project plugin?

level: juniorimportance: must knowfreq 55%

answer

  1. Plugin<Settings> vs Plugin<Project>
  2. applied in settings.gradle(.kts)
  3. runs in initialization phase
  4. include/includeBuild/pluginManagement
  5. configures the whole build

basics

~10 s

A Settings plugin implements Plugin<Settings> and is applied in settings.gradle(.kts). It configures the build as a whole (which projects exist, repositories, plugin resolution), unlike a Project plugin that configures one project's tasks and dependencies.

solid answer

~30 s

A Settings plugin implements `Plugin<Settings>` and is applied via the `plugins {}` block (or `apply`) in `settings.gradle(.kts)`. Its `apply(Settings)` receives the `Settings` object, so it runs during the *initialization phase* — before any project is configured. That lets it do things only possible there: call `include`/`includeBuild`, configure `pluginManagement`, `dependencyResolutionManagement`, `enableFeaturePreview`, and register lifecycle hooks. A `Plugin<Project>`, by contrast, gets a `Project` and runs during the configuration phase to set up tasks, dependencies, and extensions for a single project. The two operate on entirely different model objects and lifecycle phases.

code

kotlin · 7 lines
kotlin
// settings.gradle.kts
plugins {
    id("com.example.conventions.settings") version "1.2.0"
}

rootProject.name = "my-app"
include(":core", ":web")

go deeper

for a junior

Name the interface (Plugin<Settings>), where it's applied (settings.gradle), and that it configures the whole build rather than one project.

for a middle

Tie it to the initialization phase and list the Settings-only capabilities: include/includeBuild, pluginManagement, dependencyResolutionManagement.

for a senior

Explain why the phase distinction forces the model split, and when you'd reach for a settings plugin over conventions in buildSrc.

for a principal

Frame it as the org-wide standardization seam: one settings plugin enforces repos, version catalogs, and cache config across many repos.

## The two plugin types Gradle's `Plugin<T>` interface is generic over the object it configures. The two main specializations are: - **`Plugin<Project>`** — the common case. Applied inside a `build.gradle(.kts)`, it receives a `Project` and runs during the **configuration phase**. It registers tasks, declares dependencies, adds extensions, etc. - **`Plugin<Settings>`** — applied inside `settings.gradle(.kts)`, it receives a `Settings` and runs during the **initialization phase**, *before* any project's build script is evaluated. ## Why the distinction matters Gradle has three phases: **initialization → configuration → execution**. The `Settings` object only exists in initialization. Certain things can *only* be done there: - declaring the project structure: `include(":app")`, `includeBuild("../shared")` - `pluginManagement { repositories {} }` — where plugins are resolved from - `dependencyResolutionManagement { repositories {}; versionCatalogs {} }` — centralized repos & version catalogs - `rootProject.name = ...` - `enableFeaturePreview(...)` A `Plugin<Settings>` is therefore the right tool to package and share that cross-build setup — for example, a company "conventions" settings plugin that wires the same repositories, a shared version catalog, and build-cache configuration into every repo. ## Minimal implementation ```kotlin class MySettingsPlugin : Plugin<Settings> { override fun apply(settings: Settings) { settings.pluginManagement { repositories { gradlePluginPortal() } } settings.dependencyResolutionManagement { repositories { mavenCentral() } } } } ``` ## Where it can be applied from A settings plugin must come from somewhere already resolvable when settings is evaluated: an included build via `pluginManagement { includeBuild(...) }`, `buildSrc`, a precompiled script plugin, or a published plugin available in the `pluginManagement` repositories.

  • Why can't a Settings plugin register tasks?
    Tasks belong to a Project, which doesn't exist yet during initialization. The Settings plugin runs before any project is created, so it has no Project to add tasks to.
  • Where must the settings plugin itself be available from?
    It must be resolvable when settings is evaluated — from buildSrc, an included build under pluginManagement, a precompiled settings convention plugin, or a repository declared in pluginManagement.

If a Project plugin furnishes one room, a Settings plugin draws the floor plan: which rooms exist and where everyone shops for materials.

saying these in an interview costs you the question

  • Claiming you apply a settings plugin in build.gradle — it goes in settings.gradle(.kts).
  • Thinking a settings plugin can configure tasks or dependencies of a specific project directly.

context