How does an init script differ from a settings script and a build script, and when would you reach for an init script specifically?
answer
- phase + delegate + scope distinguish them
- init=Gradle, settings=Settings, build=Project
- init runs first, out of repo
- settings defines structure
- init for mirrors/credentials/CI policy
basics
~20 sEach runs in a different phase with a different delegate: init script (initialization, Gradle object), settings script (initialization, Settings), build script (configuration, Project). Use an init script for machine-/CI-wide config you don't commit to the repo.
solid answer
~40 sThe three script types differ by **phase**, **delegate**, and **scope**. An **init script** runs first, in the initialization phase, with the `Gradle` object as delegate; it lives outside the project (Gradle user home, distribution, or `--init-script`) and configures the *whole machine/invocation*. A **settings script** (`settings.gradle(.kts)`) also runs in initialization, delegate `Settings`, and defines the *project structure* (which modules exist, `pluginManagement`, `dependencyResolutionManagement`, included builds). A **build script** (`build.gradle(.kts)`) runs in configuration, delegate `Project`, and configures *one project's* plugins, dependencies, and tasks. Reach for an init script when the concern is environment-specific and must not be checked in — a corporate mirror, credentials from env vars, a build-scan/CI plugin, or a fleet-wide policy — because it applies uniformly to every build on the machine without touching the repository.
go deeper
Distinguish the three by name and roughly what each does (init=global, settings=structure, build=one project).
Map each to phase + delegate + scope and give a correct use case for choosing an init script.
Reason about reproducibility-from-checkout and why machine-specific config stays out of the repo.
Define org guidance: what lives in init scripts vs convention plugins vs settings, and how that affects build reproducibility and governance.
## The three script types side by side | Script | File(s) | Phase | Delegate | Scope | |---|---|---|---|---| | Init | `~/.gradle/init.gradle(.kts)`, `init.d/`, `--init-script` | Initialization (earliest) | `Gradle` | Whole invocation / machine | | Settings | `settings.gradle(.kts)` | Initialization | `Settings` | Project structure | | Build | `build.gradle(.kts)` | Configuration | `Project` | A single project | ## Why the delegate matters Unqualified calls in a script resolve against its delegate. So in a build script `repositories {}` configures *that project's* repositories; in an init script you'd typically write `allprojects { repositories {} }` because the delegate is `Gradle`, not a `Project`. Knowing the delegate tells you what you can configure directly. ## Ordering Within a single invocation: init scripts → `settings.gradle(.kts)` → (`settingsEvaluated`) → project configuration (`build.gradle(.kts)` per project) → execution. Init scripts genuinely run first, which is why they can influence everything downstream. ## When to pick an init script Choose an init script when **all three** hold: the config is *environment/machine-specific*, it should *not* be committed to the repo, and it should apply to *every* build run on that machine. Canonical examples: - A corporate artifact mirror / repository credentials. - Applying an org-wide build-scan or telemetry plugin in CI. - Enforcing policy ("no SNAPSHOT dependencies in release builds"). - Per-developer toggles that differ across machines. If the config is *part of the project* (its modules, its plugins, its dependencies), it belongs in settings/build scripts (or a convention plugin), not an init script — otherwise the build isn't reproducible from a clean checkout. ```kotlin // build script: configures THIS project (delegate = Project) dependencies { implementation("org.example:lib:1.0") } // init script: configures EVERY project (delegate = Gradle) allprojects { repositories { mavenCentral() } } ``` ## Rule of thumb Project-defining → settings script. Project-configuring → build script (or convention plugin). Machine/CI-wide, out-of-repo → init script.
- Why is putting project module structure in an init script a bad idea?Module structure is part of the project and belongs in settings.gradle so the build is reproducible from a clean checkout. In an init script it lives outside the repo, so other developers/CI wouldn't get the same structure.
- Both init and settings scripts run in the initialization phase — what orders them?Init scripts run before the settings script; the settingsEvaluated hook (registerable from an init script) fires after settings.gradle is evaluated.
saying these in an interview costs you the question
- Saying a build script runs in the initialization phase — it runs in configuration.
- Recommending init scripts for project-intrinsic config like modules or dependencies that must be reproducible from a checkout.