If you build Android apps, you have probably hit this fork in the road: Google Play wants an .aab (Android App Bundle), but direct downloads, sideloading, and most OEM stores want an .apk. Understanding the difference — and knowing how to produce both from one build — saves a lot of confusion at release time.

What is an APK?

An APK (Android Package) is a complete, installable app. It contains your compiled code plus all the resources for every device configuration: every screen density, every CPU architecture (arm64, armeabi-v7a, x86_64), and every language string. When a user installs an APK, they download all of that, even the parts their device does not need.

APKs are universal and simple. Any Android device can install a correctly-signed APK, which is why APKs remain the format for sideloading, direct distribution, and most non-Google stores.

What is an AAB (Android App Bundle)?

An AAB is a publishing format, not an installable app. It contains your code and resources in a structured way, but it is not what runs on a phone. Instead, Google Play takes your AAB and generates optimized split APKs for each device — delivering only the resources and native libraries that specific device needs.

The result is a dramatically smaller download for each user. A single AAB might produce dozens of targeted APK variants behind the scenes, one per device profile.

Why Google Play requires AAB

Since 2021, Google Play requires new apps to be published as AABs (with exceptions for some use cases like instant apps and certain APK expansion files). The motivation is size: smaller downloads mean more installs, less storage used, and less bandwidth on mobile networks.

When you need each format

  • Google Play → upload an .aab.
  • Direct download / sideload / your own install page → host an .apk.
  • Most OEM stores (Huawei, Xiaomi, OPPO, VIVO, Samsung, Honor) → typically an .apk (check each store's current requirements).
  • Internal QA / beta via a download page → an .apk for instant install.

How to build both from one build

You do not need two separate build configurations. From a standard Gradle release build you can produce both:

  1. The AAB for Play: build with ./gradlew :app:bundleRelease. The output appears in app/build/outputs/bundle/release/.
  2. A universal APK for direct distribution: either build with ./gradlew :app:assembleRelease, or use Google's bundletool to generate a universal APK from your AAB: bundletool build-apks --bundle=app.aab --output=app.apks --mode=universal

Sign both with the same release key. Consistent signing means users can move between your direct APK and a store install without conflicts (the package is recognized as the same app).

Bundletool: the bridge between formats

bundletool is Google's official command-line tool for working with AABs. It can turn an AAB into a set of split APKs for a specific device, or into a single universal APK. It is also what Play uses internally. For teams that want to ship the size-optimized bundles to Play but still offer a one-tap direct install elsewhere, bundletool is the link.

Size: does it matter for direct distribution?

For direct APK downloads, a universal APK is larger than Play's per-device split APKs because it bundles every density and ABI. For most apps this is a reasonable trade-off — the simplicity of one file outweighs the extra megabytes. If size is critical (a very large app on a slow network), consider publishing per-ABI APKs and routing users to the right one by architecture.

Common pitfalls

  • Wrong format to the wrong store: uploading an APK to Play or an AAB to a store that expects an APK will fail at submission.
  • Different signing keys: if your direct APK and store build use different keys, they count as different apps and cannot update one another. Use one key.
  • Forgetting to test the APK: the AAB-to-APK path via bundletool occasionally surfaces resource issues that the Play path hides. Always install the direct APK on a real device before publishing.

Conclusion

APK and AAB are not competitors — they serve different stages of distribution. Build an AAB for Google Play's optimized delivery, and build (or extract via bundletool) a universal APK for everything else: OEM stores, direct downloads, beta testing, and internal rollout. Produce both from the same signed release build, and your app reaches every Android channel without extra engineering effort.