Skip to content

gplay vs gradle-play-publisher: which is the better Google Play CLI in 2026?

If you build Android apps with Gradle, gradle-play-publisher (GPP) has probably crossed your radar as the way to publish to Google Play without leaving your build script. It’s a solid, focused tool. But if you’ve ever needed to do anything on Play Console beyond uploading an AAB and updating a listing — subscriptions, purchase verification, crash reports, reviews, reports — you’ve hit its ceiling.

gplay takes a different bet: one static binary, all of Play Console.

  • GPP is Gradle-native. If your entire release flow lives inside ./gradlew, it fits naturally: ./gradlew publishRelease and you’re done.
  • gplay is Play Console-complete. Subscriptions with base plans and offers, in-app products, purchase verification, vitals (crashes, ANRs, startup, battery), reviews, financial reports, users and permissions, Managed Google Play custom apps, Google Checks compliance — 250+ commands across 6 Google APIs.
  • Different runtime shape. GPP is a Gradle plugin (JVM, needs your build project). gplay is a static Go binary — no runtime, works from any shell, any container, any language.
Capability gplay gradle-play-publisher
Upload AAB/APK to tracks
Staged rollouts (fractional)
Promote between tracks
Store listings (title, description, graphics)
Screenshots
Release notes per track and locale
Deobfuscation & native debug symbols
Subscriptions (base plans, offers, prices) ✅ Full
In-app products
Server-side purchase verification
Vitals: crashes, ANRs, performance
Reviews (list + reply)
Financial & statistics reports (GCS)
Users & permission grants
Managed Google Play custom apps
Google Checks compliance
Runtime Single 12MB Go binary Gradle plugin (JVM + build)
Works outside the Android project ⚠️ Needs Gradle context
JSON-first output for agents/scripts ❌ (Gradle output)
--dry-run on writes ⚠️ Task-level only

GPP covers the “publish a build” story well. Where gplay pulls ahead is everything after publish: monitor how it’s doing, monetize it, keep it compliant, respond to users.

Pick gradle-play-publisher if all of these are true:

  • Your release flow lives entirely inside Gradle and you like it that way.
  • You publish AABs and update listings — no subscriptions, no purchase verification, no vitals monitoring from CI.
  • Your Play Console work outside of ./gradlew publishRelease is done manually in the web UI, and you’re happy with that split.

That’s a real use case. If it’s yours, GPP is well-designed for it.

Pick gplay if any of these are true:

  • You have subscriptions, in-app products, or offers to manage — GPP does not cover monetization at all.
  • You want to verify purchases server-side without pulling in the full Google API Java client and OAuth boilerplate.
  • You want to check crashes, ANRs, or performance metrics from CI (fail the pipeline on regressions).
  • You reply to reviews or download reports as part of your release ritual.
  • You’re driving Play Console from an AI coding agent (Claude Code, Cursor, OpenClaw, Hermes Agent) — gplay’s JSON-first output, explicit long flags, --dry-run, and --help discoverability are built for agents. GPP was not.
  • You want the same tool to work on macOS, Linux CI, Windows PowerShell, and inside minimal Docker containers — no JVM, no Gradle, no project context needed.
  • You’re using something other than Gradle (Bazel, Buck, custom build scripts, Kotlin Multiplatform with non-Gradle targets).

Yes. A common pattern: GPP handles the “upload from ./gradlew” step for developer ergonomics, and gplay handles everything else in CI — post-release rollout monitoring, subscription changes, crash alerts, review replies, monthly report downloads.

They don’t conflict. They read the same service account. Nothing stops you from using GPP for uploads and gplay for the rest.

This one is easy to overlook until you feel it.

  • gradle-play-publisher runs inside your Gradle build: JVM startup, plugin resolution, project sync. On a Mac laptop that’s a few seconds; on a cold CI runner it can be 30-60 seconds before the first upload byte moves.
  • gplay is a 12 MB static Go binary. Cold-start is under 50 ms. In a minimal alpine:latest container, gplay tracks list returns before Gradle has finished parsing your build.gradle.

For an agent that runs dozens of Play API calls in a single session (checking crashes, updating listings, promoting rollouts) the difference compounds.

If you’re using an AI coding agent (Claude Code, Cursor, Codex, Gemini CLI, Aider, Cline, Windsurf, Continue, GitHub Copilot CLI, OpenClaw, Hermes Agent), gplay was designed for you:

  • JSON output by default — the agent parses it directly, no scraping.
  • Explicit long flags--package, --track, --rollout; no ambiguous short flags to hallucinate.
  • --help on every command — agents discover the surface instead of guessing.
  • --dry-run on every write — safe preview before executing.
  • No interactive prompts — nothing blocks on stdin.
  • 16 ready-made Agent Skills — install with npx skills add tamtom/gplay-cli-skills and your agent knows the real Google Play workflows.

GPP’s output is Gradle task output. An agent trying to drive it has to parse human-facing logs. It works, but it’s fragile.

Terminal window
brew install tamtom/tap/gplay
gplay setup --auto # installs gcloud, enables the API, creates a service account
gplay apps list # you're already in

Full install options (Homebrew, install script, Windows PowerShell, manual binaries) on the installation page. Full command reference at /reference/.

If you’re on GPP today and want to see what “the rest of Play Console” looks like, start with these three: gplay vitals crashes query, gplay subscriptions list, and gplay reviews list. Chances are you’ll find a workflow you were doing in the web UI that suddenly belongs in CI.