Pre-compiled Script Plugins
The simplest plugin you can develop is called a precompiled script plugins.
These are Kotlin (.kts
) or Groovy (.gradle
) scripts.
They behave like normal Gradle plugins, but you write them using the same syntax as regular build scripts.
Some benefits of precompiled script plugins:
-
Encapsulation: Keep your
build.gradle(.kts)
files clean by moving reusable logic into named plugins. -
Tooling support: Full IDE support, like autocomplete and navigation.
-
Avoid boilerplate: No need to write full plugin classes or register plugins manually.
-
Faster adoption: Use familiar script syntax while reaping the benefits of structured plugin development.
Convention Plugins
Most precompiled script plugins are used as convention plugins. A Gradle term for reusable build logic that applies standard plugin configurations, defaults, and behaviors across many projects.
Convention plugins are especially useful in large or multi-project builds where consistency is important.
They typically look like this:
plugins {
`java-library`
checkstyle
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
checkstyle {
maxWarnings = 0
// ...
}
tasks.withType<JavaCompile> {
options.isWarnings = true
// ...
}
dependencies {
testImplementation("junit:junit:4.13")
// ...
}
plugins {
id 'java-library'
id 'checkstyle'
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
checkstyle {
maxWarnings = 0
// ...
}
tasks.withType(JavaCompile) {
options.warnings = true
// ...
}
dependencies {
testImplementation("junit:junit:4.13")
// ...
}
And are applied in other projects like this:
plugins {
`java-library-convention`
}
plugins {
id 'java-library-convention'
}
Structuring Precompiled Script Plugins
Precompiled script plugins are typically placed in either:
-
A dedicated
buildSrc
directory in your build, or -
A separate included build (often named
build-logic
).
1. Using buildSrc
Precompiled script plugins or convention plugins will often be found in the special buildSrc
directory:
.
└── buildSrc
├── build.gradle.kts
└── src
└── main
└── kotlin
└── myproject.java-conventions.gradle.kts
.
└── buildSrc
├── build.gradle
└── src
└── main
└── groovy
└── myproject.java-conventions.gradle
2. Using a Composite Build
Precompiled script plugins or convention plugins will often be found in a Composite Build with a name similar to build-logic
:
build-logic
├── settings.gradle.kts
├── build.gradle.kts
└── src
└── main
└── kotlin
└── myproject.java-conventions.gradle.kts
build-logic
├── settings.gradle
├── build.gradle
└── src
└── main
└── groovy
└── myproject.java-conventions.gradle
Applying a Precompiled Script Plugin
You apply a precompiled script plugin using its ID, derived from the script filename (excluding the .gradle.kts
or .gradle
extension).
plugins {
id("myproject.java-conventions")
}
plugins {
id("myproject.java-conventions")
}
The script itself acts as the plugin.
There is no need to explicitly implement the Plugin
interface; a requirement for binary plugins.
Publishing a Precompiled Script Plugin
You can publish a precompiled script plugin to a repository, either a public one such as the Gradle Plugin Portal, or a private artifact repository like Maven, Artifactory, or Nexus.
However, publishing precompiled script plugins is not typical or recommended (they are meant for internal use only). To publish them, you should first convert the precompiled script plugin into a binary plugin.
Example of a Precompiled Script Plugin
Let’s walk through creating a simple convention plugin using a precompiled script plugin in buildSrc
.
1. Create a buildSrc
directory
In the root of your project, add a buildSrc
directory:
. // root project
├── ... // other project dirs and files
└── buildSrc
├── build.gradle.kts
└── src
└── main
└── kotlin
. // root project
├── ... // other project dirs and files
└── buildSrc
├── build.gradle
└── src
└── main
└── groovy
2. Add a build file
Create buildSrc/build.gradle.kts
with the supporting build logic your convention plugin will need to compile:
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
}
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
}
3. Create a plugin script
Inside buildSrc/src/main/kotlin
or buildSrc/src/main/groovy
, write your convention plugin as a .gradle(.kts)
file:
.
└── buildSrc
├── build.gradle.kts
└── src
└── main
└── kotlin
└── myproject.java-conventions.gradle.kts
In this example, the myproject.java-conventions.gradle(.kts)
file contains the following code:
plugins {
id("java")
}
// Disable the test report for the individual test task
tasks.named<Test>("test") {
reports.html.required = false
}
// Share the test report data to be aggregated for the whole project
configurations.create("binaryTestResultsElements") {
isCanBeResolved = false
isCanBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("test-report-data"))
}
outgoing.artifact(tasks.test.map { task -> task.getBinaryResultsDirectory().get() })
}
repositories {
mavenCentral()
}
plugins {
id 'java'
}
// Disable the test report for the individual test task
test {
reports.html.required = false
}
// Share the test report data to be aggregated for the whole project
configurations {
binaryTestResultsElements {
canBeResolved = false
canBeConsumed = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.DOCUMENTATION))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType, 'test-report-data'))
}
outgoing.artifact(test.binaryResultsDirectory)
}
}
repositories {
mavenCentral()
}
The name of the script (myproject.java-conventions.gradle(.kts)
) becomes the plugin ID: myproject.java-conventions
.
4. Apply the plugin in your project
In the build.gradle(.kts)
of a consuming project, apply the plugin:
plugins {
id("myproject.java-conventions")
}
dependencies {
testImplementation("junit:junit:4.13")
}
plugins {
id 'myproject.java-conventions'
}
dependencies {
testImplementation 'junit:junit:4.13'
}
Next Step: Learn about Binary Plugins >>