# Tony's rules for Gradle plugin authors

DevFeed: [Tony's rules for Gradle plugin authors](<https://devfeed.tech/articles/tony-s-rules-for-gradle-plugin-authors-30467.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/tonys-rules-for-gradle-plugin-authors-28k3>)

Author: Tony Robalik

Published: 2022-04-25T01:30:01Z

Content type: tutorial

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [ordering](<https://devfeed.tech/topics/ordering.md>), [debug](<https://devfeed.tech/topics/debug.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [container](<https://devfeed.tech/tags/container.md>), [context](<https://devfeed.tech/tags/context.md>), [debug](<https://devfeed.tech/tags/debug.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [gradle-plugin](<https://devfeed.tech/tags/gradle-plugin.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [lazy](<https://devfeed.tech/tags/lazy.md>), [plugin](<https://devfeed.tech/tags/plugin.md>), [releases](<https://devfeed.tech/tags/releases.md>), [rules](<https://devfeed.tech/tags/rules.md>), [software](<https://devfeed.tech/tags/software.md>), [types](<https://devfeed.tech/tags/types.md>)

## AI overview

An advisory article for Gradle plugin authors that presents practical rules for separating configuration and execution, using lazy configuration and callbacks, avoiding cross-project configuration and internal APIs, and designing stable public APIs.

## Source excerpt

The Gradle API surface is huge. It is also littered with unspoken rules whose enforcement mechanism is inscrutable runtime failures. I want to say "we can do better," but really, we can't. The best we can do at present is mitigate by internalizing the following rules. A rule by any other name I call these "rules," but in many cases they can be only guidelines. Sometimes we have to break a rule because there really is no other way to achieve our goals. Nevertheless, the following rules were all learned the hard way, and should only be violated consciously. The rules An important bit of context for the following is that a Gradle build is divided into two1 primary phases: configuration and execution. Most of the rules are about what it is permissible to do in one phase or the other. Each phase carries with it different restrictions. Don't do expensive computations in the configuration phase It slows down the build. Such computations should be encapsulated in a task action. Avoid the create method on Gradle's container types Use register instead. Avoid the all callback on Gradle's container types Use configureEach instead. Don't assume your plugin is applied after another Instead, use pluginManager.withPlugin(). Avoid making any ordering assumptions of any kind Lazy configuration, callbacks, and provider chains are the name of the game. Don't access a Project instance inside a task action It breaks the configuration cache, and will eventually be deprecated. Don't access another project's Project instance This is called cross-project configuration and is extremely fragile. It creates implicit, nearly un-modelable dependencies between projects and can only lead to grief. Instead, share artifacts across projects by declaring dependencies. It also breaks the experimental project isolation feature, but that won't be truly relevant for a while. Avoid afterEvaluate It introduces subtle ordering issues which can be very challenging to debug. What you're looking for is probably