# Convention Plugins

version 9.2.0

A convention plugin is a type of pre-compiled script plugin.

A convention plugin is a plugin that normally configures existing core and community plugins with your own conventions (i.e. default values) such as setting the Java version by using `java.toolchain.languageVersion = JavaLanguageVersion.of(17)`.

Convention plugins are also used to enforce project standards and help streamline the build process. They can apply and configure plugins, create new tasks and extensions, set dependencies, and much more.

Convention plugins are preferred over `allprojects {}` / `subprojects {}` blocks.

## Creating a convention plugin

Convention plugins are typically placed in either:

- `buildSrc/` — simplest approach, automatically on the classpath of the build.

- an included build (commonly named `build-logic/`) — more scalable, especially for multi-project builds or organizations.

Any `.gradle.kts` (or `.gradle`) script file in `src/main/kotlin/` or `src/main/groovy/` of that plugin build becomes a precompiled script plugin, and its file name defines the plugin ID.

## Example of a convention plugin

Convention plugins really shine when you want to capture organization-wide defaults once, and apply them consistently across many subprojects.

Imagine you want every module that publishes artifacts to use the same Maven configuration. Instead of copy–pasting `publishing { … }` blocks into every `build.gradle(.kts)`, you can extract them into a convention plugin.

The project layout is as follows:

    .
    ├── core/
    ├── utils/
    ├── platform/
    └── buildSrc/
        ├── build.gradle.kts
        └── src/
            └── main/
                └── kotlin/
                    └── java-conventions.gradle.kts

    .
    ├── core/
    ├── utils/
    ├── platform/
    └── buildSrc/
        ├── build.gradle
        └── src/
            └── main/
                └── groovy/
                    └── java-conventions.gradle

Here’s a precompiled script plugin that standardizes publishing. Notice how it sets the `group` and `version` from the root project and configures a local Maven repository in `build/repo`:

buildSrc/src/main/kotlin/myproject.publishing-conventions.gradle.kts

    plugins {
        id("maven-publish")
    }

    group = rootProject.group
    version = rootProject.version

    publishing {
        repositories {
            maven {
                url = uri(rootProject.layout.buildDirectory.dir("repo"))
            }
        }
    }

buildSrc/src/main/groovy/myproject.publishing-conventions.gradle

    plugins {
        id 'maven-publish'
    }

    group = rootProject.group
    version = rootProject.version

    publishing {
        repositories {
            maven {
                url = layout.buildDirectory.dir("repo")
            }
        }
    }

With this in place, any subproject can opt in simply by applying `id("myproject.publishing-conventions")`.

Our `platform` subproject applies the convention plugin alongside the `java-platform` plugin. It declares dependency constraints and sets up a publication for the BOM:

platform/build.gradle.kts

    plugins {
        `java-platform`
        id("myproject.publishing-conventions")
    }

    publishing {
        publications {
            create("maven", MavenPublication::class.java) {
                from(components["javaPlatform"])
            }
        }
    }

platform/build.gradle

    plugins {
        id 'java-platform'
        id 'myproject.publishing-conventions'
    }

    publishing {
        publications {
            maven(MavenPublication) {
                from components.javaPlatform
            }
        }
    }