settings.gradle is the root Gradle configuration file that defines the structure of a multi-module project: which modules are included in the build, which plugins are available, and how dependencies are resolved. While build.gradle describes how to build each module, settings.gradle describes which modules make up the project. According to Gradle Documentation, 2025, proper configuration of settings.gradle reduces configuration time of a multi-module project by 25% due to optimized module resolution. The file is executed during the Initialization phase — the first phase in the Gradle build lifecycle.
Key Takeaways
settings.gradle (or settings.gradle.kts for Kotlin DSL) is a file that Gradle executes during the Initialization phase. It defines the project hierarchy, includes modules, and configures repositories for plugins and dependencies. Without settings.gradle, Gradle does not know which modules to build and which plugins are available. In a single-module project, settings.gradle may be absent — Gradle uses default values, but it is required for multi-module projects.
The settings.gradle file is located at the project root, alongside the root build.gradle. A typical root project structure: settings.gradle.kts, build.gradle.kts, gradle.properties, local.properties, gradle/wrapper/. settings.gradle is executed before build.gradle — during the Initialization phase, Gradle builds the project tree (Project in Gradle API). After Initialization completes, Configuration begins — the execution of each module's build.gradle.
Historically, settings.gradle appeared in Gradle 0.7 (2010) and initially contained only include directives. As Gradle evolved, pluginManagement (Gradle 6.8), dependencyResolutionManagement (Gradle 7.0), and versionCatalogs (Gradle 7.4) were added. Modern settings.gradle is a powerful configuration file that centralizes plugin, repository, and version management for the entire project. Google enforces these capabilities in the Android Gradle Plugin starting with AGP 8.0.
settings.gradle manages the project structure and global settings (plugins, repositories). build.gradle manages the build (dependencies, Android configurations, tasks). settings.gradle is executed first and has access to the Settings API. build.gradle is executed afterward and has access to the Project API. No module-level configurations (android block, dependencies) can be in settings.gradle — that would be an error.
The include directive is the core of settings.gradle. It tells Gradle which modules should participate in the build. The include argument is a string with the module path: include(":app") includes a module at the root level, include(":core:network") includes a module in the core/network/ subdirectory. The colon at the beginning indicates that the path is relative to the project root. After include, Gradle automatically finds build.gradle in the specified directory and adds the module to the project tree.
Each include creates a Project in the Gradle API with the name equal to the include string. The project name is used in implementation(project(":module")) in other modules' build.gradle files. If a module is not included via include, referencing it from another module will cause a “Project not found” error. Android Studio IDE also uses settings.gradle to display modules in the Project panel — modules without include are not visible in the file tree.
include supports included builds and composite builds via includeBuild("../library-project"). This allows including entire Gradle projects as external modules. Included builds are useful for developing libraries in parallel with the application: changes in the library are immediately visible in the application without publishing to a Maven repository. In a production build, includeBuild is replaced with a regular Maven dependency.
// settings.gradle.kts — typical structure
rootProject.name = "MyApp"
// Application modules
include(":app")
include(":core:network")
include(":core:database")
include(":core:ui")
include(":feature:home")
include(":feature:profile")
include(":feature:settings")
// Including an external library (composite build)
includeBuild("../my-analytics-lib") {
dependencySubstitution {
substitute(module("com.example:analytics"))
.using(project(":analytics"))
}
}
pluginManagement is a block in settings.gradle that determines where to load Gradle plugins from. It was introduced in Gradle 6.8 for centralized plugin management before they are applied. Inside pluginManagement are: repositories (list of repositories for finding plugins), resolutionStrategy (version resolution rules), and plugins (explicit plugin version declarations). If pluginManagement is not defined, Gradle uses the repositories from build.gradle — but plugins are searched for only after they are declared, which leads to errors if a plugin is not found.
In Android projects, pluginManagement is required if using Version Catalogs or Convention Plugins. Without pluginManagement, Gradle cannot find the com.android.application plugin when applied in build.gradle.kts. A typical configuration: repositories contains google() (Android plugins), mavenCentral() (third-party plugins), and gradlePluginPortal() (official Gradle plugins).
pluginManagement also supports plugins — declaring plugins with versions that are then applied in build.gradle without specifying a version. This centralizes plugin versions: if 10 modules apply kotlin-android, the version is specified once in pluginManagement. Important: pluginManagement.plugins is only a declaration. The plugin itself is applied in build.gradle via plugins { id("org.jetbrains.kotlin.android") }.
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url = "https://jitpack.io" }
}
// Plugin versions — centrally
plugins {
id("com.android.application") version "8.7.0"
id("com.android.library") version "8.7.0"
id("org.jetbrains.kotlin.android") version "2.0.21"
id("com.google.devtools.ksp") version "2.0.21-1.0.25"
}
resolutionStrategy {
// Forced plugin version for all modules
eachPlugin {
if (requested.id.id == "com.google.gms.google-services") {
useVersion("4.4.2")
}
}
}
}
plugins {
// Applying plugins — apply false (do not apply to root)
id("com.android.application") apply false
id("org.jetbrains.kotlin.android") apply false
}
dependencyResolutionManagement is a block in settings.gradle that centrally manages repositories for all modules. It was introduced in Gradle 7.0 as an alternative to declaring repositories in each build.gradle. Inside the block are repositoriesMode (mode: PREFER_PROJECT, PREFER_SETTINGS, or FAIL_ON_PROJECT_REPOS) and repositories (list of repositories). If repositoriesMode = PREFER_SETTINGS, module-level repositories are ignored — only the centralized list is used.
repositoriesMode can take three values. PREFER_SETTINGS — repositories from build.gradle are ignored, only those from settings.gradle are used. PREFER_PROJECT — build.gradle repositories take priority over settings.gradle. FAIL_ON_PROJECT_REPOS — if a module declares its own repositories, Gradle throws an error. For new projects, PREFER_SETTINGS is recommended — it guarantees that all modules use the same repositories and eliminates duplication.
repositoriesMode = FAIL_ON_PROJECT_REPOS is especially useful in teams: if a developer adds a repository to only one module while others do not see it, it causes a “works on my machine” issue. FAIL_ON_PROJECT_REPOS forces all repositories to be declared centrally in settings.gradle, preventing such situations. Google recommends FAIL_ON_PROJECT_REPOS for all Android projects starting with AGP 8.0.
dependencyResolutionManagement {
// FAIL_ON_PROJECT_REPOS — all repositories only here
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = "https://jitpack.io" }
// Private Maven repository
maven {
url = "https://maven.pkg.github.com/company/internal-lib"
credentials {
username = providers.gradleProperty("gpr.user")
.getOrNull() ?: System.getenv("GPR_USER") ?: ""
password = providers.gradleProperty("gpr.key")
.getOrNull() ?: System.getenv("GPR_KEY") ?: ""
}
}
}
}
// In build.gradle module, repositories are no longer needed!
// All repositories centralized in settings.gradle
Version Catalogs is a centralized way to manage dependency versions via a TOML file. Starting from Gradle 7.4, Version Catalogs are the recommended mechanism for all Android projects. The gradle/libs.versions.toml file contains three sections: [versions] (versions), [libraries] (dependencies), [plugins] (plugins). In settings.gradle, the Version Catalog is connected via @Suppress("UnstableApiUsage") and enableFeaturePreview("VERSION_CATALOGS") (in older Gradle versions).
After connecting the Version Catalog, module dependencies in build.gradle are specified via libs: implementation(libs.retrofit). The IDE provides autocompletion for libs. The catalog automatically generates type-safe accessors: libs.retrofit, libs.kotlin.coroutines, libs.bundles.compose. Bundles are groups of dependencies that can be included with a single line. Version Catalogs also support inheritance — multiple TOML files can be connected.
Benefits of Version Catalogs: single place for versions (no need to search through all build.gradle files); type-safe access (a typo in libs name is caught at compile time, not runtime); automatic updates (Dependabot and Renovate support TOML); compatibility with Convention Plugins. Google Firebase and AndroidX distribute their own TOML catalogs. For migrating to Version Catalogs, there are plugins that automatically transfer versions from build.gradle to TOML.
# gradle/libs.versions.toml
[versions]
agp = "8.7.0"
kotlin = "2.0.21"
composeBom = "2024.12.01"
retrofit = "2.11.0"
coroutines = "1.9.0"
[libraries]
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
compose-ui = { module = "androidx.compose.ui:ui" }
[bundles]
compose = ["compose-ui", "compose-material3"]
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
includeBuild is a directive for creating a composite build: including an external Gradle project as part of the current build. Unlike include (which includes a module), includeBuild includes an entire project with its own settings.gradle, modules, and plugins. Composite builds are used for: developing libraries (analytics, networking) in parallel with the application; including Convention Plugins from a separate repository; integrating build-logic modules.
Incubating Features are experimental Gradle options that are enabled via enableFeaturePreview("FEATURE_NAME"). In AGP 8.7+, available features include: TYPESAFE_PROJECT_ACCESSORS (type-safe access to projects in a multi-module project: instead of project(":core:network"), you can write projects.core.network), STABLE_CONFIGURATION_CACHE (stable configuration caching), ARTIFACT_TRANSFORM_FOR_INTERNAL_TEST (artifact transformation). Incubating features can be enabled in production, but the API may change in future versions.
Gradle Enterprise and Build Scan are also configured via settings.gradle: plugins { id("com.gradle.enterprise") } with a gradleEnterprise block. Build Scan is a cloud service that shows detailed information about each build: execution time for each task, caching, errors. Enabling Build Scan helps diagnose build speed issues. Build Scan is free for open-source projects.
// Incubating features
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
// Gradle Enterprise / Build Scan
plugins {
id("com.gradle.enterprise") version "3.18"
}
gradleEnterprise {
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlwaysIf(true)
}
}
// Using type-safe project accessors in build.gradle
// Instead of: implementation(project(":core:network"))
// You can: implementation(projects.core.network)
Frequently Asked Questions
For a single-module project, Gradle can use default values. However, for AGP 8+, it is recommended to always have settings.gradle, as pluginManagement and dependencyResolutionManagement are required for proper Version Catalog and Convention Plugin functionality.
include includes a module from the current project (a single module tree). includeBuild includes an external Gradle project as a composite build. includeBuild is convenient for developing libraries in the same repository or including Convention Plugins.
Add include(":module:name") to settings.gradle and create a directory with build.gradle. Android Studio does this automatically when creating a module via File → New → New Module. After adding, perform Sync Project with Gradle Files.
No, pluginManagement is a block exclusively for settings.gradle. It is executed during the Initialization phase, before any build.gradle files are executed. In build.gradle, plugins are only applied, not managed.
Each module would have to declare repositories in its own build.gradle. This leads to code duplication and risk of desynchronization (one module has a repository, another does not). dependencyResolutionManagement centralizes repositories and prevents “works on my machine” errors.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also