bundletool
is the underlying tool that Android Studio, the Android Gradle
plugin, and Google Play use to build an Android App Bundle, and convert an app
bundle into the various APKs that are deployed to devices. Android SDK Bundles
and their APKs are built with bundletool
as well. bundletool
is also
available to you as a command line tool, so you can build app bundles and SDK
bundles yourself, and recreate Google Play's server-side build of your app's
APKs or your
runtime-enabled SDK's
APKs.
Download bundletool
If you haven't already done so, download bundletool
from the
GitHub repository.
Build and test an app bundle
You can use Android Studio or the bundletool
command line tool to build your
Android App Bundle and test generating APKs from this app bundle.
Build an app bundle
You should use Android Studio and the Android plugin for Gradle to
build and sign an Android App Bundle.
However, if using the IDE is not an option (for example, because you're using a
continuous build server), you can also
build your app bundle from the command line
and sign it using
jarsigner
.
For more information about building app bundles with bundletool
,
see Build an app bundle using bundletool.
Generate a set of APKs from your app bundle
After you build your Android App Bundle, you should test how Google Play
uses it to generate APKs and how those APKs behave when deployed to a device.
There are two ways you should consider testing your app bundle: locally using the
bundletool
command line tool and through Google Play by
uploading your bundle to the Play Console
and using a test track. This section explains how to use bundletool
to test your
app bundle locally.
When bundletool
generates APKs from your app bundle, it includes them in a
container called an APK set archive, which uses the .apks
file
extension. To generate an APK set for all device configurations your app
supports from your app bundle, use the bundletool build-apks
command, as
shown below.
bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
If you want to deploy the APKs to a device, you need to also include your app's
signing information, as shown in the command below. If you do not specify
signing information, bundletool
attempts to sign your APKs with a debug key
for you.
bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks --ks=/MyApp/keystore.jks --ks-pass=file:/MyApp/keystore.pwd --ks-key-alias=MyKeyAlias --key-pass=file:/MyApp/key.pwd
The table below describes the various flags and options you can set when using
the bundletool build-apks
command in greater detail.
Flag | Description |
---|---|
--bundle=path |
(Required) Specifies the path to the app bundle you built using Android Studio. To learn more, read Build your project. |
--output=path |
(Required) Specifies the name of the output `.apks` file, which contains all the APK artifacts for your app. To test the artifacts in this file on a device, go to the section about how to deploy APKs to a connected device. |
--overwrite |
Include this flag if you want to overwrite any existing output file with
the same path you specify using the --output option. If you
don't include this flag and the output file already exists, you get a
build error.
|
--aapt2=path |
Specifies a custom path to AAPT2.
By default, bundletool includes its own version of AAPT2.
|
--ks=path |
Specifies the path to the deployment keystore used to
sign the APKs. This flag is optional. If you don't include it,
bundletool attempts to sign your APKs with a debug signing
key.
|
--ks-pass=pass:password or --ks-pass=file:/path/to/file |
Specifies your keystore's password. If you're
specifying a password in plain text, qualify it with pass: .
If you're passing the path to a file that contains the password, qualify
it with file: . If you specify a keystore using
the --ks flag without specifying --ks-pass ,
bundletool prompts you for a password from the command line.
|
--ks-key-alias=alias |
Specifies the alias of the signing key you want to use. |
--key-pass=pass:password or --key-pass=file:/path/to/file |
Specifies the password for the signing key. If you're
specifying a password in plain text, qualify it with pass: .
If you're passing the path to a file that contains the password, qualify
it with file: . If this password is identical to the one for the keystore itself, you can omit this flag. |
--connected-device |
Instructs bundletool to build APKs that target the
configuration of a connected device. If you don't include this flag,
bundletool generates APKs for all device configurations your
app supports.
|
--device-id=serial-number |
If you have more than one connected device, use this flag to specify the serial ID of the device to which you want to deploy your app. |
--device-spec=spec_json |
Use this flag to provide a path to a
.json file that specifies the device configuration you want
to target. To learn more, go to the section about how to
Generate and use device specification JSON files.
|
--mode=universal |
Set the mode to universal if you want
bundletool to build only a single APK that includes all of
your app's code and resources such that the APK is compatible with all
device configurations your app supports.
Note: Keep in mind, these APKs are larger than those optimized for a particular device configuration. However, they're easier to share with internal testers who, for example, want to test your app on multiple device configurations. |
--local-testing
|
Use this flag to enable your app bundle for local testing.
Local testing allows for quick, iterative testing cycles without the need
to upload to Google Play servers.
For an example of how to test module installation using the
|
Deploy APKs to a connected device
After you generate a set of APKs, bundletool
can deploy the right
combination of APKs from that set to a connected device.
For example, if you have a connected device running Android 5.0 (API level 21)
or higher, bundletool
pushes the base APK, feature module APKs, and
configuration APKs required to run your app on that device. Alternatively, if
your connected device is running Android 4.4 (API level 20) or lower,
bundletool
looks for a compatible multi-APK and deploys it to your device.
To deploy your app from an APK set, use the install-apks
command and specify
the path of the APK set using the
--apks=/path/to/apks
flag, as
shown below. (If you have multiple devices connected, specify a target device
by adding the --device-id=serial-id
flag.)
bundletool install-apks --apks=/MyApp/my_app.apks
Generate a device-specific set of APKs
If you'd rather not build a set of APKs for all device configurations your app
supports, you can build APKs that target only the configuration of a connected
device using the --connected-device
option, as shown below. (If you have
multiple devices connected, specify a target device by including the
--device-id=serial-id
flag.)
bundletool build-apks --connected-device --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
Generate and use device specification JSON files
bundletool
is capable of generating an APK set that targets a device
configuration specified by a JSON file. To first generate a JSON file for a
connected device, run the following command:
bundletool get-device-spec --output=/tmp/device-spec.json
bundletool
creates a JSON file for your device in the directory the tool is
located. You can then pass it to bundletool
to generate a set of APKs that
target only the configuration described in that JSON file as follows:
bundletool build-apks --device-spec=/MyApp/pixel2.json --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
Manually create a device specification JSON
If you don't have access to the device for which you want to build a targeted APK set (for example, a friend wants to try your app with a device you don't have on-hand), you can manually create a JSON file using the following format:
{
"supportedAbis": ["arm64-v8a", "armeabi-v7a"],
"supportedLocales": ["en", "fr"],
"screenDensity": 640,
"sdkVersion": 27
}
You can then pass this JSON to the bundle extract-apks
command, as described
in the previous section.
Extract device-specific APKs from an existing APK set
If you have an existing APK set and you want to extract from it a subset of APKs
that target a specific device configuration, you can use the extract-apks
command and specify a device specification JSON, as follows:
bundletool extract-apks --apks=/MyApp/my_existing_APK_set.apks --output-dir=/MyApp/my_pixel2_APK_set.apks --device-spec=/MyApp/bundletool/pixel2.json
Measure the estimated download sizes of APKs in an APK set
To measure the estimated download sizes of APKs in an APK set as they would
be served compressed over-the-wire, use the get-size total
command:
bundletool get-size total --apks=/MyApp/my_app.apks
You can modify the behavior of the get-size total
command using the
following flags:
Flag | Description |
---|---|
--apks=path |
(Required) Specifies the path to the existing APK set file whose download size is measured. |
--device-spec=path |
Specifies the path to the device spec file (from
get-device-spec or constructed manually) to use for matching.
You can specify a partial path to evaluate a set of configurations.
|
--dimensions=dimensions |
Specifies the dimensions used when computing the size estimates. Accepts
a comma-separated list of: SDK , ABI ,
SCREEN_DENSITY , and LANGUAGE . To measure across
all dimensions, specify ALL .
|
--instant |
Measures the download size of the instant-enabled APKs instead of the
installable APKs. By default, bundletool measures the
installable APK download sizes.
|
--modules=modules |
Specifies a comma-separated list of modules in the APK set to consider
in the measurement. The bundletool command automatically
includes any dependent modules for the specified set. By default, the
command measures the download size of all modules installed during the
first download.
|
Build and test an app bundle with an SDK bundle dependency (experimental)
You can use bundletool
to build an Android App Bundle with an Android SDK
Bundle dependency and test generating APKs from it.
Build an app bundle with an SDK bundle dependency
You can build your Android App Bundle with an Android SDK Bundle dependency from the command line and sign it using jarsigner.
Each app bundle module includes a Module Protocol Buffer (.pb
) file:
runtime_enabled_sdk_config.pb
. This file contains the list of SDKs
that an app bundle module depends on. For the full definition of this file,
see the
runtime_enabled_sdk_config.proto file.
To build an app bundle with an SDK bundle dependency, follow the same guide to
build an app bundle using bundletool, but this time ensure
that you add a runtime_enabled_sdk_config.pb
file to each app module's zip
file with compiled code and resources.
Some notable fields in the runtime_enabled_sdk_config.pb
file:
Certificate digest: the SHA-256 digest of the certificate for the key used to sign the SDK's APKs. This corresponds to the certificate in the
SdkMetadata.pb
file in the Android SDK Archive format.Resources Package ID: the package ID that all resources in this SDK are remapped to when generating APKs for embedding the SDK into the app. This enables backward compatibility.
An SDK can appear only in one module; if multiple modules depend on the same SDK, this dependency should be deduplicated and moved to the base module. Different modules can't depend on different versions of the SDK.
Generate APKs from an app bundle with an SDK bundle dependency
To generate APKs from your app bundle, you can follow the same steps as in
Generate a set of APKs from your app bundle
or
Generate a device-specific set of APKs,
but this time you should provide the bundletool build-apks
command with the
SDKs the app depends on. These SDKs can be provided in SDK bundle format or SDK
Archive format.
You can provide the SDKs as SDK bundles by adding the --sdk-bundles
flag, as
follows:
bundletool build-apks --bundle=app.aab --sdk-bundles=sdk1.asb,sdk2.asb \ --output=app.apks
You can provide the SDKs as SDK archives by adding the --sdk-archives
flag,
as follows:
bundletool build-apks --bundle=app.aab --sdk-archives=sdk1.asar,sdk2.asar \ --output=app.apks
Build and test an SDK bundle (experimental)
You can use bundletool
to build an Android SDK Bundle and test generating the
files needed for installation and distribution.
Build an SDK bundle
You can build your Android SDK Bundle (ASB) from the command line and sign it using jarsigner.
To build an SDK bundle, follow these steps:
Generate the SDK bundle's manifest and resources in proto format by following the same steps as for an app bundle.
Package your SDK's compiled code and resources into a base zip file, like you would do with an app module.
Generate an
SdkModulesConfig.pb.json
file and anSdkBundleConfig.pb.json
file, matching the format described in the Android SDK Bundle specification.Build your SDK bundle by using the
bundletool build-sdk-bundle
command as follows:
bundletool build-sdk-bundle --sdk-bundle-config=SdkBundleConfig.pb.json \ --sdk-modules-config=SdkModulesConfig.pb.json \ --modules=base.zip --output=sdk.asb
The table below describes the various flags and options you can set when using
the bundletool build-sdk-bundle
command in greater detail.
Flag | Description |
---|---|
--modules |
(Required) The module file that you want to build the final Android SDK Bundle from. |
--output |
(Required) Path to where the Android SDK Bundle should be built. |
--sdk-modules-config |
(Required) Path to a JSON file that describes the configuration of the SDK modules. To learn how to format the JSON file, see the Android SDK Bundle specification. |
--sdk-bundle-config |
Path to a JSON file that describes the configuration of the SDK bundle. To learn how to format the JSON file, see the Android SDK Bundle specification |
--metadata-file |
Specifies the file to include as metadata in the Android SDK Bundle.
The format of the flag value is
<bundle-path>:<physical-file> ,
where <bundle-path> denotes the file location inside the
SDK bundle's metadata directory, and <physical-file> is
an existing file that contains the raw data to be stored. The flag can be
repeated.
|
--overwrite |
If set, any previous existing output is overwritten. |
Generate APKs from an SDK bundle
After you build your Android SDK Bundle, you can test an SDK bundle locally by
generating its APKs using the bundletool build-sdk-apks
command, as shown in
the following code.
When bundletool
generates APKs from your SDK bundle, it includes them in a
container called an APK set archive, which uses the .apks
file extension.
bundletool
generates a single standalone APK from the SDK bundle that targets
all device configurations.
bundletool build-sdk-apks --sdk-bundle=sdk.asb --output=sdk.apks
If you want to deploy the ASB to a device, you need to also include your app's
signing information, as shown in the following command. If you don't specify
signing information, bundletool
attempts to sign your APKs with a debug key for
you.
bundletool build-sdk-apks --sdk-bundle=sdk.asb --output=sdk.apks \ --ks=keystore.jks \ --ks-pass=file:/keystore.pwd \ --ks-key-alias=KeyAlias \ --key-pass=file:/key.pwd
The table below describes the various flags and options you can set when using
the bundletool build-sdk-apks
command in greater detail.
Flag | Description |
---|---|
--sdk-bundle |
(Required) Path to SDK bundle. Must have the extension
.asb .
|
--output |
(Required) By default, the path to where the APK set archive
should be created. Alternatively, if you use
--output-format=DIRECTORY ,
this is the path to the directory where generated APKs should be stored.
|
--ks |
Path to the keystore that should be used to sign the generated APKs. |
--ks-key-alias |
Alias of the key to use in the keystore to sign the generated APKs. |
--key-pass |
Password of the key in the keystore to use to sign the generated APKs.
If you're passing the password in clear text, you must prefix the value with
pass: , for example pass:qwerty . If the password
is the first line of a file, you must prefix the value with
file: , for example file:/tmp/myPassword.txt ). If
this flag isn't set, the keystore password is tried. If that fails, the
command line terminal prompts you for a password.
|
--ks-pass |
Password of the keystore to use to sign the generated APKs.
If you're passing the password in clear text, you must prefix the value with
pass: , for example pass:qwerty . If the password
is the first line of a file, you must prefix the value with
file: , for example
file:/tmp/myPassword.txt ). If this flag isn't set, the
command line terminal prompts you for a password. |
--aapt2 |
Path to the AAPT2 binary to use. |
--output-format |
Specifies the output format for generated APKs. By default, it's set to
APK_SET , which outputs APKs into the APK set archive that is
created. If set to DIRECTORY , it outputs APKs into the
directory specified by --output . |
--verbose |
If set, prints extra information about the command execution in the standard output. |
--version-code |
SDK version code. This is the version code used by the Android platform to install the APK, not the SDK version. It can be set to an arbitrary value. If not set, it defaults to 0. |
--overwrite |
If set, any previous existing output is overwritten. |
Generate an SDK Archive from an SDK bundle
After you upload your Android SDK Bundle to your distribution channel, for
example Google Play, the Android SDK bundle is transformed into an Android SDK
Archive (.asar
) for distribution to app developers through Maven. For more
details about the format, see the
SDK Archive format specification.
After you build your Android SDK Bundle, you can test the generation of an
Android SDK Archive locally using the bundletool build-sdk-asar
command, as
shown in the following code.
bundletool build-sdk-asar --sdk-bundle=sdk.asb --output=sdk.asar \ --apk-signing-key-certificate=keycert.txt
The table below describes the various flags and options you can set when using
the bundletool build-sdk-asar
command in greater detail.
Flag | Description |
---|---|
--apk-signing-key-certificate |
(Required) Path to the SDK APK signing certificate. This is the
certificate corresponding to the key that you used to sign the APKs in the
build-sdk-apks command.
|
--output |
(Required) Path to where the .asar file should be
created.
|
--sdk-bundle |
(Required) Path to the SDK bundle. Must have the extension
.asb .
|
--overwrite |
If set, any previous existing output is overwritten. |
Runtime-enabled SDK formats (experimental)
Runtime-enabled SDKs introduce two Android file formats: the
Android SDK Bundle (.asb
), used to publish the runtime-enabled
SDK to app stores, and the Android SDK Archive (.asar
),
used to distribute the runtime-enabled SDK on Maven.
The Android SDK Bundle format
An SDK Bundle is a publishing format for runtime-enabled SDKs. It contains all the SDK code and resources, including the code from any libraries the SDK depends on. It doesn't include the code and resources of other runtime-enabled SDKs that the SDK depends on.
An Android SDK Bundle is a signed zip file that contains the extension .asb
.
The SDK code and resources are organized similarly to what you would find in
an APK. An ASB also contains several configuration files that are used to aid
the generation of the installable APKs.

The following list describes some of the Android SDK Bundle files in more detail:
SdkBundleConfig.pb
: A configuration file in proto format, containing the list of runtime-enabled SDKs that your SDK depends on. For the full definition, see thesdk_bundle_config.proto
file.modules.resm
: A zip file containing all the data needed to generate the APKs from the SDK.SdkModulesConfig.pb
: A configuration file in proto format. This file contains the SDK name, version, and class name of the SDK entry point for the framework (SandboxedSdkProvider
). For the full definition, see thesdk_modules_config.proto
file.base/
: The single module containing the SDK code and resources.manifest/
: The manifest of the SDK in proto format.dex/
: The compiled code in DEX format. Multiple DEX files can be provided.res/
,lib/
,assets/
: These directories are identical to those in a typical APK. Paths in these directories are preserved when generating the SDK's APKs.root/
: This directory stores files that are later relocated to the root of the SDK APKs. For example, it might include Java-based resources that your SDK loads using theClass.getResource()
method. Paths within this directory are also preserved.BUNDLE-METADATA
: This directory includes metadata files that contain information useful for tools or app stores. Such metadata files might include ProGuard mappings and the complete list of your SDK's DEX files. Files in this directory are not packaged into your SDK's APKs.
The Android SDK Archive format
An Android SDK Archive is the distribution format of a runtime-enabled SDK on
Maven. It's a zip file that contains the file extension .asar
. It contains
all information that is needed by the app build tools to generate an Android
App Bundle that depends on your runtime-enabled SDK.

The following list describes some of the Android SDK Bundle files in more detail:
SdkMetadata.pb
: A configuration file in proto format, containing the SDK name, version, and the certificate digest for the key used to sign the APKs generated for this SDK. For the full definition, see thesdk_metadata.proto
file.modules.resm
: A zip file containing all the data needed to generate the APKs from the SDK. This is the same as the.resm
file in the Android SDK Bundle.AndroidManifest.xml
: The manifest file of the SDK in text XML format.
Additional resources
To learn more about using bundletool
, try the following resource.
Codelabs
- Your First Android App Bundle,
a codelab that explores the basic principles of Android App Bundles and shows
you how to quickly get started with building your own using Android Studio.
This codelab also explores how to test your app bundles
using
bundletool
.