A multi-project build in Gradle consists of one root project, and one or more subprojects.

Creating a multi-project build

A basic multi-project build contains a root project and a single subproject. This is a structure of a multi-project build that contains a single subproject called app:

Example 1. Basic multi-project build
Project layout
.
├── app
│   ...
│   └── build.gradle
└── settings.gradle
Project layout
.
├── app
│   ...
│   └── build.gradle.kts
└── settings.gradle.kts

This is the recommended project structure for starting any Gradle project. The build init plugin also generates skeleton projects that follow this structure - a root project with a single subproject.

Note that the root project does not have a Gradle build file, only a settings file that defines the subprojects to include.

settings.gradle
rootProject.name = 'basic-multiproject'
include 'app'
settings.gradle.kts
rootProject.name = "basic-multiproject"
include("app")

In this case, Gradle will look for a build file in the app directory.

We can view the structure of a multi-project build by running the gradle projects command.

> gradle -q projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'basic-multiproject'
\--- Project ':app'

To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :app:tasks

Let’s say the app subproject is a Java application by applying the application plugin and configuring the main class:

app/build.gradle
plugins {
    id 'application'
}

application {
    mainClass = 'com.example.Hello'
}
app/build.gradle.kts
plugins {
    id("application")
}

application {
    mainClass.set("com.example.Hello")
}
app/src/main/java/com/example/Hello.java
package com.example;

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

We can then run the application by executing the run task from the application plugin.

> gradle -q run
Hello, world!

And that’s how simple it is to create a basic multi-project build.

Adding subprojects

Let’s say we want to add another subproject called lib to the previously created project. All we need to do is add another include statement in the root settings file:

settings.gradle
rootProject.name = 'basic-multiproject'
include 'app'
include 'lib'
settings.gradle.kts
rootProject.name = "basic-multiproject"
include("app")
include("lib")

Gradle will then look for the build file for the new subproject in the lib/ subdirectory of the project:

Example 2. Multi-project build with two subprojects
Project layout
.
├── app
│   ...
│   └── build.gradle
├── lib
│   ...
│   └── build.gradle
└── settings.gradle
Project layout
.
├── app
│   ...
│   └── build.gradle.kts
├── lib
│   ...
│   └── build.gradle.kts
└── settings.gradle.kts

Next, will explore how build logic can be shared between subprojects and how subprojects can depend on one another.

Naming recommendations

As your project grows, naming and consistency gets increasingly more important. To keep your builds maintainable, we recommend the following:

  1. Keep default project names for subprojects: It is possible to configure custom project names in the settings file. However, it’s an unnecessary extra effort for the developers to keep track of which project belongs to what folders.

  2. Use kebab case formatting for all project names: A kebab case formatting is when all letters lowercase, words separated with a dash (‘-’) character (e.g.kebab-case-formatting). This is already the de-facto pattern for many large projects. Besides, Gradle supports name abbreviation for kebab case names.

  3. Define the root project name in the settings file: The ´rootProject.name´ effectively assigns a name to the build as a whole, which is used in reports like build scans. If the root project name is not set, the name will be the container directory name, which can be unstable (i.e. you can check out your project to any directory).