nebula.lint: a linter for Gradle build scripts
A pluggable and configurable linter tool for identifying and reporting on patterns of misuse or deprecations in Gradle scripts.
At a glance
- What is it?
- The Gradle Lint plugin from nebula-plugins is a pluggable, configurable linter for Gradle scripts, built for centralised build teams who want a shared house style enforced across many repositories. It works through a rules list, it warns rather than rewrites, and it does not support Kotlin build scripts.
- Who is it for?
- Adopt nebula.lint if you maintain build scripts across several repositories and want a shared style enforced mechanically rather than by review comments, and if your scripts are written in Groovy. Do not adopt it for a Kotlin build script setup, because the README states Kotlin scripts are unsupported and asks you to switch to Groovy, and do not expect it to fix anything, since the api and implementation checks only produce warnings.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Groovy, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A linter aimed at build script reviewers, not application code
The Gradle Lint plugin is described as a pluggable and configurable linter tool for identifying and reporting on patterns of misuse or deprecations in Gradle scripts and related files. The subject is the build, not the application.
That is a narrow target and it is the point of the project. Build scripts are usually reviewed less carefully than application code, they accumulate copy and paste from older templates, and a centralised build tools team is often the only group that sees all of them at once. The README says the plugin assists such a team in gently introducing and maintaining a standard build script style across their organisation.
The word gently is doing work. The plugin reports; it does not rewrite. The api and implementation section makes that explicit, saying that while it is great to have automatic fix, not having it is worse, so warning about the problem with the same detail as before is much better than a broken experience with new Gradle configurations.
The implementation language is Groovy, which matches the subject it inspects, and the project is published both to the Gradle Plugin Portal and to Maven Central under com.netflix.nebula. The support badge in the README reads active, and the release list shows v21.3.0 on 2026-10-05 after v21.2.3 on 2026-09-04 and v21.2.2 on 2026-08-27.
Applying the plugin, and the rule that root project must be covered
Installation is the standard Gradle plugin route, and the README asks you to take the latest version from the Gradle plugin portal and add it to build.gradle.
buildscript { repositories { mavenCentral() } }
plugins {
id 'nebula.lint' version '<latest version from the Gradle plugin portal>'
}There is a second way in, using the older buildscript classpath form with the Maven Central coordinates.
buildscript {
repositories { mavenCentral() }
dependencies {
classpath 'com.netflix.nebula:gradle-lint-plugin:latest.release'
}
}
apply plugin: 'nebula.lint'Both routes end with the plugin applied. Which one you choose is mostly a matter of which style the rest of your build uses, since the plugins block is the modern form and the classpath form is what many existing enterprise builds already look like.
The constraint that catches people is the multi module one. The README marks it as important: for now, in a multi-module build you must apply lint to the root project, at a minimum. That is a hard requirement rather than a recommendation, and the reason is structural. A lint run that only covers a subproject cannot see the whole build, and rules that depend on cross project knowledge, such as dependency declarations, would be checked against an incomplete picture.
The repository contains an example directory with its own build.gradle, which is the fastest way to see a working configuration.
Where the rules live: gradleLint.rules, init.gradle or apply from
Rules are selected with a list on the gradleLint extension.
gradleLint.rules = ['all-dependency'] // add as many rules here as you'd likeThe comment tells you the shape of the configuration: a list of rule names, as many as you want. The README uses all-dependency as the example, and does not enumerate the rest, which is one of the reasons the full documentation lives in the wiki rather than in the README.
Where that assignment happens is a more interesting decision, and the README gives two placements for an enterprise build.
The first is an init.gradle script, which applies to every build on the machine or in the CI environment that uses it. The second is a Gradle script that is included through the apply from mechanism, which lets you keep the rules in version control as a file that repositories point at.
For multimodule projects the README recommends applying the plugin in an allprojects block.
allprojects {
apply plugin: 'nebula.lint'
gradleLint.rules = ['all-dependency'] // add as many rules here as you'd like
}The difference in approach between init.gradle and apply from is about control. An init script can enforce a standard on builds you do not own, which is how a centralised team reaches every repository in the organisation without asking each team to change anything. A shared script applied with apply from needs cooperation from each repository, but it is versioned alongside your code and its own history is visible.
That is the design decision a team has to make before the first lint run, and the plugin itself does not make it for you.
api and implementation: warnings only, and why the fix is missing
Support for the api and implementation configurations arrived in v15.0.0, and the README explains the current state in unusual detail.
The feature shows warnings around api and implementation configurations. The reason it stays at warnings is stated plainly: doing the major work of keeping track of declared configurations and then replacing code with the proper configuration was more than the maintainers wanted to take on, so they decided to show warnings for now. The work includes finding dependency information for non resolvable configurations, which requires looking into the parents.
There is also a dependency on an upstream Gradle issue. The README says that if gradle/gradle#11106 lands some day, they could definitely enhance this experience. Until then, the plugin cannot reliably rewrite a dependency declaration into the right configuration, and a rewrite that is wrong in some cases is worse than no rewrite at all.
The design reasoning is worth copying even if you disagree with the outcome. A linter that offers a fix it cannot apply correctly turns a warning into a build break. So the plugin keeps the diagnostic detail identical to what it was before and leaves the edit to the developer.
For a team that wants the api and implementation cleanup automated, this is the gap to check before adopting, since it is the one rule area where the tool stops short of the outcome people usually want.
The hard limitation: no Kotlin build scripts
The README has a section headed Warning, and it contains one item. The plugin does not support Kotlin build scripts, and it asks you to switch to a Groovy build script if you want to use linting. The linked issue is number 166.
This is the limitation that decides adoption for a lot of teams, because the direction of travel in the Gradle ecosystem is toward Kotlin DSL for build scripts. A linter that only reads Groovy scripts covers the older half of that world.
The failure mode is worth understanding. The plugin inspects Gradle scripts, and the way it recognises a dependency declaration or a deprecated call depends on the script syntax. A Kotlin script uses a different grammar for the same build logic, so the patterns the rules look for do not appear in the source the plugin reads. The result is not a crash but silence, which is worse in a way, because a build that lints cleanly may simply not have been linted.
The pragmatic workaround, if you must have both, is to keep the lint target on the Groovy scripts in the build and to check whether the Kotlin scripts are simply skipped or whether they produce false negatives. The README does not describe either behaviour, so the only way to know is to try it against a repository with both kinds of script and read what the output does not mention.
Why ESLint is the reference point
The README says the plugin is inspired by the excellent ESLint tool for Javascript, and by the formatting in NPM's eslint-friendly-formatter package. That single sentence explains most of the design, so it is worth unpacking rather than repeating.
The ESLint model is a linter with a pluggable rule set, where the rules are named, individually enabled, and reported through a common formatter. That is exactly the gradleLint.rules list model, and the choice of a friendly formatter matters for adoption: build script lint output is read by many people who are not build engineers, so output that reads like a code review is easier to act on than a wall of stack traces.
The comparison with a stock formatter also sets a limit. ESLint can autofix many of its rules because JavaScript syntax is regular and the fixes are local. Gradle build scripts are configuration, not expressions in a single language, and the same option has several equivalent spellings that are correct in different contexts. That is why the api and implementation work stops at warnings, and why a general claim that this is ESLint for Gradle would set the wrong expectation.
The genuine alternative, then, is not another Gradle plugin but a different approach to the same problem: codifying build conventions as Gradle conventions, enforced by the build itself rather than reported by a linter. The difference is who carries the work. A convention plugin makes the correct form the easy form, so a misconfigured build fails to compile rather than producing a warning someone has to read.
Licence, releases and the shape of the repository
The plugin is licensed under Apache 2.0, with the copyright line naming Netflix, Inc. across 2015, 2018 and 2019. That is a permissive licence with an explicit patent grant, which is a comfortable fit for a build tool that lands in many internal repositories.
The repository is not archived and the last push was on 2026-10-19, so the project is receiving changes. The release numbering is tied to the year, with v21.3.0 published on 2026-10-05, and the releases land on both the Gradle Plugin Portal and Maven Central, which means CI can consume a pinned version rather than a moving build.
The repository layout is a conventional Gradle plugin project: a src directory with the plugin code, an example directory with a working build, a gradle wrapper with gradlew and gradlew.bat, a gradle.lockfile, a settings.gradle and a build.gradle, plus an issues directory and a CONTRIBUTING.md file. The presence of the lockfile is worth noting for anyone building the plugin itself, since it is how the project keeps its own dependency resolution reproducible.
The documentation gap is the same one the README advertises. The full documentation lives in the project wiki, and the README is deliberately a short landing page that tells you how to apply the plugin and where to look for the rest.
Editorial conclusion
Adopt nebula.lint if you maintain build scripts across several repositories and want a shared style enforced mechanically rather than by review comments, and if your scripts are written in Groovy. Do not adopt it for a Kotlin build script setup, because the README states Kotlin scripts are unsupported and asks you to switch to Groovy, and do not expect it to fix anything, since the api and implementation checks only produce warnings. Before you add it, decide where the rules will live, an init.gradle script or a shared script applied with apply from, confirm that the plugin is applied to the root project of a multi module build, and read the wiki, since the README points there for the full documentation rather than describing the rule set itself.
Frequently asked questions
What does the nebula.lint Gradle plugin do?
It is a pluggable and configurable linter that identifies and reports patterns of misuse or deprecations in Gradle scripts and related files. The README says it helps a centralised build tools team introduce and maintain a standard build script style across an organisation.
How do I apply the nebula.lint plugin to a build?
Add it to build.gradle with the plugins block using id 'nebula.lint' and a version from the Gradle plugin portal, or use the buildscript classpath form with com.netflix.nebula:gradle-lint-plugin:latest.release and then apply plugin: 'nebula.lint'.
How are lint rules configured in nebula.lint?
Rules are set as a list on the gradleLint extension, for example gradleLint.rules = ['all-dependency']. The README recommends defining them in an init.gradle script or in a shared script applied with the Gradle apply from mechanism for an enterprise build.
Does nebula.lint support Kotlin build scripts?
No. The README has a warning section stating that the plugin does not support Kotlin build scripts and asking you to switch to a Groovy build script if you want linting, with issue number 166 linked.
Does the nebula.lint plugin fix api and implementation problems automatically?
No, it only shows warnings. The README says that tracking declared configurations and replacing code with the proper configuration was too much work for now, and that a broken experience would be worse than a warning.
Does nebula.lint have to be applied to every module in a multi-module build?
The README states that for now, in a multi-module build you must apply lint to the root project at a minimum. For multimodule projects it recommends applying the plugin in an allprojects block.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nebula-plugins-gradle-lint-plugin)Was this useful?