Use a build script to configure a project. Each Gradle project corresponds to a software component that needs to be built, like a library or an application. Each build script is associated with an object of type Project. As the build script executes, it configures this Project.

Build scripts, Settings scripts, and Init scripts

Build scripts define Project objects. Gradle uses other scripts as well:


Many top-level properties and blocks in a build script are part of the Project API. The following build script uses the property to print the name of the project:

println name
Output of gradle -q check
> gradle -q check

Both println statements print out the same property. The first uses the top-level reference to the name property of the Project object. The other statement uses the project property available to any build script, which returns the associated Project object.

Standard project properties

The Project object exposes a standard set of properties in your build script. The following table lists a few commonly used properties:

Table 1. Project Properties
Name Type Default Value



The Project instance



The name of the project directory.



The absolute path of the project.



A description for the project.



The directory containing the build script.












An AntBuilder instance

Script with other targets

The build scripts described here target Project objects. There are also settings scripts and init scripts that respectively target Settings and Gradle objects.

The Script API

When Gradle executes a Groovy build script (.gradle), it compiles the script into a class that implements Script. As a result, builds scripts have access to all of the properties and methods declared by the Script interface.

When Gradle executes a Kotlin build script (.gradle.kts), it compiles the script into a subclass of KotlinBuildScript. As a result, builds scripts have access to all visible properties and functions declared by the KotlinBuildScript type.

Declare Variables

Build scripts can declare two kinds of variables: local variables and extra properties.

Local Variables

Declare local variables with the val keyword. Local variables are only visible in the scope where they have been declared. They are a feature of the underlying Kotlin language.

Declare local variables with the def keyword. Local variables are only visible in the scope where they have been declared. They are a feature of the underlying Groovy language.

val dest = "dest"

tasks.register<Copy>("copy") {
def dest = 'dest'

tasks.register('copy', Copy) {
    from 'source'
    into dest

Extra Properties

All of Gradle’s enhanced objects, including projects, tasks, and source sets, can hold user-defined properties.

Add, read, and set extra properties via the owning object’s extra property. Alternatively, you can access extra properties via Kotlin delegated properties using by extra.

Add, read, and set extra properties via the owning object’s ext property. Alternatively, you can use an ext block to add multiple properties at once.

plugins {

val springVersion by extra("3.1.0.RELEASE")
val emailNotification by extra { "" }

sourceSets.all { extra["purpose"] = null }

sourceSets {
    main {
        extra["purpose"] = "production"
    test {
        extra["purpose"] = "test"
    create("plugin") {
        extra["purpose"] = "production"

tasks.register("printProperties") {
    val springVersion = springVersion
    val emailNotification = emailNotification
    val productionSourceSets = provider {
        sourceSets.matching { it.extra["purpose"] == "production" }.map { }
    doLast {
        productionSourceSets.get().forEach { println(it) }
plugins {
    id 'java-library'

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = ""

sourceSets.all { ext.purpose = null }

sourceSets {
    main {
        purpose = "production"
    test {
        purpose = "test"
    plugin {
        purpose = "production"

tasks.register('printProperties') {
    def springVersion = springVersion
    def emailNotification = emailNotification
    def productionSourceSets = provider {
        sourceSets.matching { it.purpose == "production" }.collect { }
    doLast {
        println springVersion
        println emailNotification
        productionSourceSets.get().each { println it }
Output of gradle -q printProperties
> gradle -q printProperties

This example adds two extra properties to the project object via by extra. Additionally, this example adds a property named purpose to each source set by setting extra["purpose"] to null. Once added, you can read and set all of these properties via extra.

This example adds two extra properties to the project object via an ext block. Additionally, this example adds a property named purpose to each source set by setting ext.purpose to null. Once added, you can read and set all of these properties just like predefined properties.

Gradle requires special syntax for adding a property so it can fail fast. For example, this allows Gradle to recognize when a script attempts to set a property that does not exist. You can access extra properties anywhere where you can access their owning object. This gives extra properties a wider scope than local variables. Subprojects can access extra properties on their parent projects.

For more information about extra properties, see ExtraPropertiesExtension in the API documentation.

Configure Arbitrary Objects

Configure arbitrary objects with configure():

class UserInfo(
    var name: String? = null, 
    var email: String? = null

tasks.register("configure") {
    val user = UserInfo().apply {
        name = "Isaac Newton"
        email = ""
    doLast {
class UserInfo {
    String name
    String email

tasks.register('configure') {
    def user = configure(new UserInfo()) {
        name = "Isaac Newton"
        email = ""
    doLast {
Output of gradle -q configure
> gradle -q configure
Isaac Newton

Configure Objects in an External Script

You can also configure arbitrary objects using an external script:

Not supported in Kotlin

The Kotlin DSL does not support arbitrary object configuration using an external script. For more information, see gradle/kotlin-dsl#659.

class UserInfo {
    String name
    String email

tasks.register('configure') {
    def userInfo = new UserInfo()
    // Apply the script
    apply from: 'other.gradle', to: userInfo
    doLast {
// Set properties.
name = "Isaac Newton"
email = ""
Output of gradle -q configure
> gradle -q configure
Isaac Newton

Helpful Groovy Syntax

Groovy provides many features to help create DSLs. These features can help you write more idiomatic build scripts, plugins, and tasks.

Looking for helpful Kotlin syntax? Check out the Kotlin reference documentation and Kotlin Koans.

Convenience Methods

Groovy adds convenience methods to the standard Java classes. For example, Iterable gets an each method, which iterates over the elements of the Iterable:

// Iterable gets an each() method
configurations.runtimeClasspath.each { File f -> println f }

For more information, see the GDK documentation.

Automatic Property Accessors

Groovy automatically converts property references into getter or setter method calls:

// Using a getter method
println project.buildDir
println getProject().getBuildDir()

// Using a setter method
project.buildDir = 'target'

Optional Parentheses on Method Calls

Groovy doesn’t require parentheses for method calls:

test.systemProperty 'some.prop', 'value'
test.systemProperty('some.prop', 'value')

List and Map Instantiation Shortcuts

Groovy provides shortcuts to define List and Map instances. For example, consider the “apply” method, which accepts a map parameter. When you apply a plugin (apply plugin:'java'), you don’t use a map literal. Plugin application uses "named parameters" instead. Named parameters and map literals use similar syntax, but named parameters don’t use wrapping brackets. When you call apply, Groovy converts the named parameter list to a map.

// List literal
test.includes = ['org/gradle/api/**', 'org/gradle/internal/**']

List<String> list = new ArrayList<String>()
test.includes = list

// Map literal.
Map<String, String> map = [key1:'value1', key2: 'value2']

// Groovy will coerce named arguments
// into a single map argument
apply plugin: 'java'

Last Closure Parameter Syntax

The Gradle DSL uses closures in many places. You can find out more about closures here. When the last parameter of a method is a closure, you can place the closure after the method call:

repositories {
    println "in a closure"
repositories() { println "in a closure" }
repositories({ println "in a closure" })

Closure Delegates

Each closure has a delegate object. Groovy uses this delegate to look up variable and method references to nonlocal variables and closure parameters. Gradle uses this for configuration closures, where the delegate object refers to the object being configured.

Example 11. Closure delegates
dependencies {
    assert delegate == project.dependencies

Default Imports

To make build scripts more concise, Gradle automatically adds a set of import statements to scripts. As a result, instead of writing throw new org.gradle.api.tasks.StopExecutionException(), you can write throw new StopExecutionException() instead.

Gradle implicitly adds the following imports to each script:

Gradle default imports
import org.gradle.*
import org.gradle.api.*
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.component.*
import org.gradle.api.artifacts.dsl.*
import org.gradle.api.artifacts.ivy.*
import org.gradle.api.artifacts.maven.*
import org.gradle.api.artifacts.query.*
import org.gradle.api.artifacts.repositories.*
import org.gradle.api.artifacts.result.*
import org.gradle.api.artifacts.transform.*
import org.gradle.api.artifacts.type.*
import org.gradle.api.artifacts.verification.*
import org.gradle.api.attributes.*
import org.gradle.api.attributes.plugin.*
import org.gradle.api.cache.*
import org.gradle.api.capabilities.*
import org.gradle.api.component.*
import org.gradle.api.credentials.*
import org.gradle.api.distribution.*
import org.gradle.api.distribution.plugins.*
import org.gradle.api.execution.*
import org.gradle.api.file.*
import org.gradle.api.flow.*
import org.gradle.api.initialization.*
import org.gradle.api.initialization.definition.*
import org.gradle.api.initialization.dsl.*
import org.gradle.api.initialization.resolve.*
import org.gradle.api.invocation.*
import org.gradle.api.jvm.*
import org.gradle.api.launcher.cli.*
import org.gradle.api.logging.*
import org.gradle.api.logging.configuration.*
import org.gradle.api.model.*
import org.gradle.api.plugins.*
import org.gradle.api.plugins.antlr.*
import org.gradle.api.plugins.catalog.*
import org.gradle.api.plugins.jvm.*
import org.gradle.api.plugins.quality.*
import org.gradle.api.plugins.scala.*
import org.gradle.api.provider.*
import org.gradle.api.publish.*
import org.gradle.api.publish.ivy.*
import org.gradle.api.publish.ivy.plugins.*
import org.gradle.api.publish.ivy.tasks.*
import org.gradle.api.publish.maven.*
import org.gradle.api.publish.maven.plugins.*
import org.gradle.api.publish.maven.tasks.*
import org.gradle.api.publish.plugins.*
import org.gradle.api.publish.tasks.*
import org.gradle.api.reflect.*
import org.gradle.api.reporting.*
import org.gradle.api.reporting.components.*
import org.gradle.api.reporting.dependencies.*
import org.gradle.api.reporting.dependents.*
import org.gradle.api.reporting.model.*
import org.gradle.api.reporting.plugins.*
import org.gradle.api.resources.*
import org.gradle.api.specs.*
import org.gradle.api.tasks.*
import org.gradle.api.tasks.ant.*
import org.gradle.api.tasks.application.*
import org.gradle.api.tasks.bundling.*
import org.gradle.api.tasks.compile.*
import org.gradle.api.tasks.diagnostics.*
import org.gradle.api.tasks.diagnostics.configurations.*
import org.gradle.api.tasks.incremental.*
import org.gradle.api.tasks.javadoc.*
import org.gradle.api.tasks.options.*
import org.gradle.api.tasks.scala.*
import org.gradle.api.tasks.testing.*
import org.gradle.api.tasks.testing.junit.*
import org.gradle.api.tasks.testing.junitplatform.*
import org.gradle.api.tasks.testing.testng.*
import org.gradle.api.tasks.util.*
import org.gradle.api.tasks.wrapper.*
import org.gradle.authentication.*
import org.gradle.authentication.http.*
import org.gradle.buildinit.*
import org.gradle.buildinit.plugins.*
import org.gradle.buildinit.tasks.*
import org.gradle.caching.*
import org.gradle.caching.configuration.*
import org.gradle.caching.http.*
import org.gradle.caching.local.*
import org.gradle.concurrent.*
import org.gradle.external.javadoc.*
import org.gradle.ide.visualstudio.*
import org.gradle.ide.visualstudio.plugins.*
import org.gradle.ide.visualstudio.tasks.*
import org.gradle.ide.xcode.*
import org.gradle.ide.xcode.plugins.*
import org.gradle.ide.xcode.tasks.*
import org.gradle.ivy.*
import org.gradle.jvm.*
import org.gradle.jvm.application.scripts.*
import org.gradle.jvm.application.tasks.*
import org.gradle.jvm.tasks.*
import org.gradle.jvm.toolchain.*
import org.gradle.language.*
import org.gradle.language.assembler.*
import org.gradle.language.assembler.plugins.*
import org.gradle.language.assembler.tasks.*
import org.gradle.language.base.*
import org.gradle.language.base.artifact.*
import org.gradle.language.base.compile.*
import org.gradle.language.base.plugins.*
import org.gradle.language.base.sources.*
import org.gradle.language.c.*
import org.gradle.language.c.plugins.*
import org.gradle.language.c.tasks.*
import org.gradle.language.cpp.*
import org.gradle.language.cpp.plugins.*
import org.gradle.language.cpp.tasks.*
import org.gradle.language.jvm.tasks.*
import org.gradle.language.nativeplatform.*
import org.gradle.language.nativeplatform.tasks.*
import org.gradle.language.objectivec.*
import org.gradle.language.objectivec.plugins.*
import org.gradle.language.objectivec.tasks.*
import org.gradle.language.objectivecpp.*
import org.gradle.language.objectivecpp.plugins.*
import org.gradle.language.objectivecpp.tasks.*
import org.gradle.language.plugins.*
import org.gradle.language.rc.*
import org.gradle.language.rc.plugins.*
import org.gradle.language.rc.tasks.*
import org.gradle.language.scala.tasks.*
import org.gradle.language.swift.*
import org.gradle.language.swift.plugins.*
import org.gradle.language.swift.tasks.*
import org.gradle.maven.*
import org.gradle.model.*
import org.gradle.nativeplatform.*
import org.gradle.nativeplatform.platform.*
import org.gradle.nativeplatform.plugins.*
import org.gradle.nativeplatform.tasks.*
import org.gradle.nativeplatform.test.*
import org.gradle.nativeplatform.test.cpp.*
import org.gradle.nativeplatform.test.cpp.plugins.*
import org.gradle.nativeplatform.test.cunit.*
import org.gradle.nativeplatform.test.cunit.plugins.*
import org.gradle.nativeplatform.test.cunit.tasks.*
import org.gradle.nativeplatform.test.googletest.*
import org.gradle.nativeplatform.test.googletest.plugins.*
import org.gradle.nativeplatform.test.plugins.*
import org.gradle.nativeplatform.test.tasks.*
import org.gradle.nativeplatform.test.xctest.*
import org.gradle.nativeplatform.test.xctest.plugins.*
import org.gradle.nativeplatform.test.xctest.tasks.*
import org.gradle.nativeplatform.toolchain.*
import org.gradle.nativeplatform.toolchain.plugins.*
import org.gradle.normalization.*
import org.gradle.platform.*
import org.gradle.platform.base.*
import org.gradle.platform.base.binary.*
import org.gradle.platform.base.component.*
import org.gradle.platform.base.plugins.*
import org.gradle.plugin.devel.*
import org.gradle.plugin.devel.plugins.*
import org.gradle.plugin.devel.tasks.*
import org.gradle.plugin.use.*
import org.gradle.plugins.ear.*
import org.gradle.plugins.ear.descriptor.*
import org.gradle.plugins.ide.*
import org.gradle.plugins.ide.api.*
import org.gradle.plugins.ide.eclipse.*
import org.gradle.plugins.ide.idea.*
import org.gradle.plugins.signing.*
import org.gradle.plugins.signing.signatory.*
import org.gradle.plugins.signing.signatory.pgp.*
import org.gradle.plugins.signing.type.*
import org.gradle.plugins.signing.type.pgp.*
import org.gradle.process.*
import org.gradle.swiftpm.*
import org.gradle.swiftpm.plugins.*
import org.gradle.swiftpm.tasks.*
import org.gradle.testing.base.*
import org.gradle.testing.base.plugins.*
import org.gradle.testing.jacoco.plugins.*
import org.gradle.testing.jacoco.tasks.*
import org.gradle.testing.jacoco.tasks.rules.*
import org.gradle.testkit.runner.*
import org.gradle.util.*
import org.gradle.vcs.*
import org.gradle.vcs.git.*
import org.gradle.workers.*

Groovy Script Variables

Groovy has two types of script variables:

  • Variables declared with a type modifier or def are visible within closures but not visible within methods.

  • Variables declared without a modifier are visible anywhere in the script.

Prefer declaring variables with def to make their scope explicit.

String localScope1 = 'localScope1'
def localScope2 = 'localScope2'
scriptScope = 'scriptScope'

println localScope1
println localScope2
println scriptScope

closure = {
    println localScope1
    println localScope2
    println scriptScope

def method() {
    try {
    } catch (MissingPropertyException e) {
        println 'localScope1NotAvailable'
    try {
    } catch(MissingPropertyException e) {
        println 'localScope2NotAvailable'
    println scriptScope
Output of groovy scope.groovy
> groovy scope.groovy
For more information about Groovy syntax, see the Groovy documentation.