What is the buildSrc directory in a Gradle build, and how does Gradle treat it?
answer
- implicit by directory name
- compiled before all build scripts
- output on every build-script classpath
- has its own build.gradle.kts
- any change busts build-script cache
basics
~10 sbuildSrc is a special directory Gradle automatically compiles into a project and puts on every build script's classpath. You put shared build logic there — custom plugins, tasks, helper classes — without publishing anything.
solid answer
~40 s`buildSrc` is an optional directory at the root of a Gradle build. If it exists, Gradle treats it as an implicit included build that is compiled **before** any project's build scripts, and its output JAR is automatically placed on the classpath of every build script in the build. That means classes, custom task types, and convention plugins defined under `buildSrc/src/main/kotlin` (or `/java`, `/groovy`) are usable in any `build.gradle.kts` without `apply from` or publishing to a repository. It has its own `build.gradle.kts` so it can declare its own dependencies (e.g. the Kotlin Gradle plugin to compile `.gradle.kts` convention plugins). It is the canonical place to de-duplicate logic across a multi-project build. The main trade-off: any change to `buildSrc` invalidates the build script cache and forces a recompile, so churn there slows every build.
code
kotlin · 18 lines// buildSrc/build.gradle.kts
plugins {
`kotlin-dsl` // lets you write *.gradle.kts convention plugins
}
repositories {
gradlePluginPortal()
}
dependencies {
// plugins your conventions apply must be on buildSrc's classpath
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0")
}
// buildSrc/src/main/kotlin/acme.java-conventions.gradle.kts
// -> usable in any module via plugins { id("acme.java-conventions") }
plugins { `java-library` }
java { toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } }go deeper
Know it is a special folder for shared build logic, auto-compiled and on every build script's classpath.
Explain it has its own build.gradle.kts, holds custom tasks/convention plugins, and is discovered implicitly.
Discuss the cache-invalidation cost and when it tips you toward a separate build-logic composite build.
Frame buildSrc within an org build-platform strategy: lifecycle isolation, build-speed budgets, and migration paths.
## What buildSrc is `buildSrc` is a **conventionally-named directory** at the root of a Gradle build (next to `settings.gradle.kts`). It is not declared anywhere — Gradle discovers it by name. When present, Gradle compiles it as a self-contained project **before evaluating any other project**, then automatically adds its compiled output to the classpath of **every** build script in the build. Think of it as "a library you write for your own build, with zero ceremony." Anything you can write in Kotlin/Java/Groovy — a custom `DefaultTask` subclass, an extension class, a `Plugin<Project>` implementation, or a precompiled `*.gradle.kts` convention script — becomes directly referenceable from any module's build script. ## Structure ``` root/ settings.gradle.kts build.gradle.kts buildSrc/ build.gradle.kts // buildSrc's OWN build file & dependencies src/main/kotlin/ com/acme/MyTask.kt // custom task type acme.java-conventions.gradle.kts // precompiled convention plugin app/ build.gradle.kts ``` `buildSrc` has its **own** `build.gradle.kts`. To author precompiled convention plugins (the `*.gradle.kts` files), you apply the `kotlin-dsl` plugin in `buildSrc/build.gradle.kts`. You also declare here any plugin dependencies your conventions need (e.g. the Kotlin or Spring Boot Gradle plugins) via their Maven coordinates. ## How Gradle treats it 1. **Implicit:** no `includeBuild` entry is needed — discovery is by directory name. 2. **Compiled first:** its classes exist before the root/sub-project scripts are evaluated. 3. **Global classpath:** the output is on every build script classpath automatically — no per-project wiring. 4. **One instance per build:** there is a single `buildSrc` for the whole build, shared by all included builds too. ## The cache-invalidation cost Because `buildSrc`'s output sits on the build-script classpath, **any** change to its sources changes that classpath. Gradle conservatively treats a changed build-script classpath as a reason to recompile and re-evaluate build scripts, and it busts the configuration cache / build-script caching. So an edit to one helper class in `buildSrc` makes the *next* build slower across the whole project. This is the main reason large builds eventually migrate shared logic to a separate `includeBuild("build-logic")` composite build (a sibling topic) — but for moderate builds `buildSrc` is the simplest, lowest-ceremony option. ## When to use it Use `buildSrc` for build logic you want shared and type-safe across modules: custom task types, convention plugins, version constants, and small helpers. Do **not** put production/application code there — it is build-time only.
- Do you need to add anything to settings.gradle.kts to enable buildSrc?No. buildSrc is discovered by its directory name automatically; unlike a composite build you do not (and must not) `includeBuild("buildSrc")`.
- Can buildSrc declare its own dependencies?Yes — it has its own build.gradle.kts where you declare dependencies (e.g. the kotlin-dsl plugin and any plugin coordinates the conventions apply).
buildSrc is like a utility module you import everywhere in your build — except Gradle wires the import for you automatically, no publishing, no apply-from.
saying these in an interview costs you the question
- Claiming you must register buildSrc in settings.gradle.kts (it is implicit).
- Thinking buildSrc holds production/application source code rather than build logic.
- Saying changes to buildSrc are free — they invalidate build-script caching.