android/gradle-recipes: 32 AGP 9.0 build customizations indexed by API
Ready-to-use recipes for common build customizations that showcase the Android Gradle plugin's public APIs and DSL.
At a glance
- What is it?
- A read-only branch of self-contained Gradle builds that demonstrate the Android Gradle plugin public APIs for version 9.0, arranged so the API name rather than the topic is the entry point. Useful as a lookup, thin as documentation.
- Who is it for?
- Treat android/gradle-recipes as a lookup table, not a dependency. If you need a working shape for Artifacts.use(), beforeVariants() or a generated source folder in AGP 9.0, the indexed recipe is the fastest reference the plugin ecosystem offers.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 12 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Thirty-two directories, one pinned plugin version
The unit of this repository is a directory, and there are thirty-two of them at the top level, each named after the operation it performs: onVariants, addGeneratedSourceFolder, transformManifest, workerEnabledTransformation, legacyTaskBridging and so on. Nothing here is packaged for consumption. There is no plugin coordinate, no library artifact and no starter template; what you get is one self-contained Gradle build per customisation, usable as a working example. The version boundary is stated in the first line of the README, which says the branch holds recipes compatible with AGP 9.0 and that recipes for other AGP versions live on the corresponding agp-* branch. That makes the plugin version, not the subject matter, the organising axis, and it changes how you read the repository. The person it serves is not a beginner looking for what a manifest merge placeholder is. It is an Android build engineer who already knows the operation they need and wants to see the AGP 9.0 shape of the call, wired in the right order, in a build file that somebody else compiled.
The API index is the part that earns the repository its keep
The README carries three separate indexes and the third one is the useful one. Themes has six buckets: Android Assets, Android Manifest, Artifact API, DSL, Dependency Resolution and Sources. Plugin Features names exactly three: Fused Library Plugin, Kotlin Multiplatform and TestFixtures. Then there is the API list, a flat run of around sixty fully qualified names mapped to recipe directories, and that inversion is what makes the repository different from reference documentation. A DSL reference tells you a method exists and what its parameters are. This index tells you which recipe actually calls it. The frequencies in that list are informative on their own. Artifacts.get() is listed against nine recipes, Artifacts.use() against six, and AndroidComponentsExtension.onVariants() against the better part of thirty, which tells you before you read a single build file that onVariants is the callback everything else hangs off. A project like this is only worth maintaining if somebody regenerates the index when recipes change, and the README does not say who does that or how the list is produced. That gap is worth keeping in mind before you rely on the index as a complete map.
Read-only branch, development on studio-main, no releases at all
Three facts about the repository's shape matter more than the feature list. First, the branch is read only. The README says contributions are only accepted on the studio-main branch and points to CONTRIBUTION.md there, so a pull request opened against agp-9.0 is aimed at the wrong target. Second, there are no GitHub releases, so there is no tag to pin to and no release note to read when a recipe changes behaviour. Version selection happens by picking a branch and nothing else. Third, no licence is recorded for the repository, which matters more here than it would for most projects: the entire value of this repository is in the contents of its build files, and those are exactly the thing you would want to copy into a commercial codebase without a licence attached. The repository is not archived and the last push was on 2026-09-17, so the work is current even though it ships without a version history. Put together, that means you are reading a moving snapshot of someone else's working notes, with no way to ask what changed or whether you may reuse it.
Getting the code: two commands, and no build step is documented
The README documents no installation, no Gradle invocation and no prerequisites, and the repository records no homepage, so there is no documented place to get the code from beyond the Git repository itself. The only two names that decide what you get are the branch names:
agp-9.0
studio-mainThe first is the default branch and holds the AGP 9.0 recipes, the second is the branch the README says accepts contributions. Check out the first, and the working tree is the thirty-two recipe directories listed above plus a README and nothing else. Check out the second instead and you are on the wrong side of the read-only notice. There is no wrapper version, no Gradle version and no prerequisite list anywhere in the documentation, so the honest description of getting this project is that you fetch a branch and read it. A first real use is a reading exercise rather than a build exercise. Pick the directory that matches the operation you need, open its build file, and lift the call sequence into your own project. Two honest caveats. The README never says which Gradle version, JDK level or wrapper the recipes pin, so whether a given recipe compiles on your toolchain is unverified from the documentation. And because there is no stated build command, you cannot tell from the README alone whether running the wrapper inside a recipe directory is expected to succeed or is only there for an editor. Both are things you find out by opening the files, which is a fair thing to ask of a code reference and an unreasonable thing to ask of a tutorial.
Most of the index points at the Artifact API
Counting the recipe directories by theme makes the project's centre of gravity clear. The Artifact API accounts for the largest cluster: createSingleArtifact, getSingleArtifact, getMultipleArtifact, addMultipleArtifact, listenToArtifacts, listenToMultipleArtifact, appendToScopedArtifacts, appendToMultipleArtifact, transformMultiple, transformAllClasses, transformDirectory and transformManifest, plus getScopedArtifacts. The names describe a consistent shape, producing a handle with get or getAll, registering a new artifact type with add, narrowing a modification to a component scope with forScope, and installing work on a produced artifact with use. Two entries in the index deserve a second look because they change where the work happens. workerEnabledTransformation is indexed against ArtifactTransformationRequest and BuiltArtifact, which points at the worker API route rather than an in-process callback. And BuiltArtifact.versionCode and BuiltArtifact.versionName are listed under listenToArtifacts, so version rewriting in these examples happens on the built artifact rather than through a manifest placeholder. If you are trying to change an APK after it is produced, that distinction is the whole design decision, and the index surfaces it without any prose explaining it.
Variant hooks, extension points and exactly three plugin features
Around the artifact work sits a smaller set of recipes that change the build rather than its outputs. The entry points are AndroidComponentsExtension.beforeVariants(), which is where selectVariants and disableTests live, onVariants(), and selector(), which is shared by selectVariants, variantOutput and allProjectsApkAction. Then there is the group that extends the plugin itself: registerExtension() together with DslExtension.Builder.build() appears under extendingAgp, and addBuildTypeUsingDslFinalize is filed under the DSL theme, which by its name suggests a build type defined and finalised through the Kotlin DSL rather than the older Groovy one. Alongside those, a handful of recipes touch the build graph rather than AGP at all, including registerPreBuild, addCustomBuildConfigFields, allProjectsApkAction and asmTransformClasses. The Plugin Features section, by contrast, stays tiny: the Fused Library Plugin, Kotlin Multiplatform and TestFixtures. That asymmetry is the honest signal about this repository's age. The variant API recipes are numerous because that surface has been growing for years, while the fused library plugin is a single new directory, and the README gives it no description beyond its name. Nothing can be said about what it fuses without opening the build file.
The route not through onVariants: resolution strategy and the legacy bridge
There are two ways to change a build in this index that do not go through the variant callbacks, and they are worth setting against the main path. The first is variantDependencySubstitutionTest, the only recipe under the Dependency Resolution theme, and the API list shows what it touches: Component.compileConfiguration, Component.runtimeConfiguration and Configuration.resolutionStrategy. A component-level resolution strategy substitutes a dependency per variant, which is a different mechanism from generating code or transforming an artifact: it changes which module gets resolved rather than what happens to the output. The second is legacyTaskBridging, indexed under both the Android Assets and Sources themes, which is the one recipe whose name is explicitly about the past. Every other directory is named after something in the current API. The existence of a bridging recipe tells you the two models coexist in AGP 9.0 rather than one having replaced the other, and it means a project that still registers named tasks in its build file is not stranded. The README does not say when to pick which, and that is the gap a reader will hit: the index shows the door, not the decision.
What the repository will not tell you
Four gaps are worth stating plainly. There is no licence recorded, so the licence question for copied build files is unanswered. There are no releases, so there is no changelog and no way to tell whether a recipe was rewritten or left alone between pushes. There is no homepage, no setup guide and no troubleshooting section, so the index is the entire documentation. And the newest parts of AGP 9.0 are the least covered, because the older Variant API recipes have had time to accumulate while the fused library plugin has one directory and a name. The practical read is that this repository is a well-organised index over a moving target, useful precisely because the API names are current, and weak precisely because nothing behind the index is versioned, licensed or explained. If your decision is whether to depend on a component, the answer is no. If your decision is what a call looks like in AGP 9.0, it is faster than anything else you can find.
Editorial conclusion
Treat android/gradle-recipes as a lookup table, not a dependency. If you need a working shape for Artifacts.use(), beforeVariants() or a generated source folder in AGP 9.0, the indexed recipe is the fastest reference the plugin ecosystem offers. Skip it if you need a licensed component to paste into a commercial build, a supported upgrade path or a tutorial, because the repository lists no license, publishes no releases and documents no build command. Verify one thing before you commit to a recipe: that your own project is actually on AGP 9.0. If it is not, move to the matching agp-* branch and expect the API index there to be a different list.
Frequently asked questions
Which branch of android/gradle-recipes should I use for my project?
Pick the branch that matches your Android Gradle plugin version. The default branch is agp-9.0 and the README says recipes for other AGP versions are on the corresponding agp-* branches, so on an older plugin you need to switch branches and read a different API index.
Can I contribute a recipe to android/gradle-recipes?
Not on the branch you are reading. The README states that the agp-9.0 branch is read only and that contributions are only accepted on the studio-main branch, pointing to CONTRIBUTION.md there.
How do I find the recipe for a specific AGP API in android/gradle-recipes?
Use the API index in the README, which maps fully qualified API names to recipe directories. For example Artifacts.get() is listed against transformManifest, perVariantManifestPlaceholder, createSingleArtifact and several others, while AndroidComponentsExtension.onVariants() appears against the largest group of recipes.
Does android/gradle-recipes publish a plugin I can add to my build?
Nothing in the repository presents a plugin coordinate or a published artifact. It is a set of self-contained build customizations laid out as one directory per recipe, with a README that serves as an index of themes and API names.
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/android-gradle-recipes)