This tutorial covers how to build a simple Android app using Bazel.
Bazel supports building Android apps using the Android rules.
This tutorial is intended for Windows, macOS and Linux users and does not require experience with Bazel or Android app development. You do not need to write any Android code in this tutorial.
What you'll learn
In this tutorial you learn how to:
- Set up your environment by installing Bazel and Android Studio, and downloading the sample project.
- Set up a Bazel workspace that contains the source code
for the app and a
MODULE.bazelfile that identifies the top level of the workspace directory. - Update the
MODULE.bazelfile to contain references to the required external dependencies, like the Android SDK. - Create a
BUILDfile. - Build the app with Bazel.
- Deploy and run the app on an Android emulator or physical device.
Before you begin
Install Bazel
Before you begin the tutorial, install the following software:
- Bazel. To install, follow the installation instructions.
- Android Studio. To install, follow the steps to download Android Studio. Execute the setup wizard to download the SDK and configure your environment.
- (Optional) Git. Use
gitto download the Android app project.
Get the sample project
For the sample project, use the tutorial Android app project in Bazel's examples repository.
This app has a single button that prints a greeting when clicked:

Figure 1. Android app button greeting.
Clone the repository with git (or download the ZIP file
directly):
git clone https://github.com/bazelbuild/examplesThe sample project for this tutorial is in examples/android/tutorial. For
the rest of the tutorial, you will be executing commands in this directory.
Review the source files
Take a look at the source files for the app.
.
├── README.md
└── src
└── main
├── AndroidManifest.xml
└── java
└── com
└── example
└── bazel
├── AndroidManifest.xml
├── Greeter.java
├── MainActivity.java
└── res
├── layout
│ └── activity_main.xml
└── values
├── colors.xml
└── strings.xml
The key files and directories are:
| Name | Location |
|---|---|
| Android manifest files | src/main/AndroidManifest.xml and src/main/java/com/example/bazel/AndroidManifest.xml |
| Android source files | src/main/java/com/example/bazel/MainActivity.java and Greeter.java |
| Resource file directory | src/main/java/com/example/bazel/res/ |
Build with Bazel
Set up the workspace
A workspace is a directory that contains the
source files for one or more software projects, and has a MODULE.bazel file at
its root.
The MODULE.bazel file may be empty or may contain references to external
dependencies required to build your project.
First, run the following command to create an empty MODULE.bazel file:
| OS | Command |
|---|---|
| Linux, macOS | touch MODULE.bazel |
| Windows (Command Prompt) | type nul > MODULE.bazel |
| Windows (PowerShell) | New-Item MODULE.bazel -ItemType file |
Running Bazel
You can now check if Bazel is running correctly with the command:
bazel info workspaceIf Bazel prints the path of the current directory, you're good to go! If the
MODULE.bazel file does not exist, you may see an error message like:
ERROR: The 'info' command is only supported from within a workspace.
Integrate with the Android SDK
Bazel needs to run the Android SDK
build tools
to build the app. This means that you need to add some information to your
MODULE.bazel file so that Bazel knows where to find them.
Add the following line to your MODULE.bazel file:
bazel_dep(name = "rules_android", version = "0.6.6")
remote_android_extensions = use_extension(
"@rules_android//bzlmod_extensions:android_extensions.bzl",
"remote_android_tools_extensions")
use_repo(remote_android_extensions, "android_tools")
android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension")
use_repo(android_sdk_repository_extension, "androidsdk")
This will use the Android SDK at the path referenced by the ANDROID_HOME
environment variable, and automatically detect the highest API level and the
latest version of build tools installed within that location.
You can set the ANDROID_HOME variable to the location of the Android SDK. Find
the path to the installed SDK using Android Studio's SDK
Manager.
Assuming the SDK is installed to default locations, you can use the following
commands to set the ANDROID_HOME variable:
| OS | Command |
|---|---|
| Linux | export ANDROID_HOME=$HOME/Android/Sdk/ |
| macOS | export ANDROID_HOME=$HOME/Library/Android/sdk |
| Windows (Command Prompt) | set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk |
| Windows (PowerShell) | $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk" |
The above commands set the variable only for the current shell session. To make them permanent, run the following commands:
| OS | Command |
|---|---|
| Linux | echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc |
| macOS | echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc |
| Windows (Command Prompt) | setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk" |
| Windows (PowerShell) | [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User) |
Optional: If you want to compile native code into your Android app, you
also need to download the Android
NDK
and use rules_android_ndk by adding the following line to your MODULE.bazel file:
bazel_dep(name = "rules_android_ndk", version = "0.1.3")
For more information, read Using the Android Native Development Kit with Bazel.
It's not necessary to set the API levels to the same value for the SDK and NDK. This page contains a map from Android releases to NDK-supported API levels.
Create a BUILD file
A BUILD file describes the relationship
between a set of build outputs, like compiled Android resources from aapt or
class files from javac, and their dependencies. These dependencies may be
source files (Java, C++) in your workspace or other build outputs. BUILD files
are written in a language called Starlark.
BUILD files are part of a concept in Bazel known as the package hierarchy.
The package hierarchy is a logical structure that overlays the directory
structure in your workspace. Each package is a
directory (and its subdirectories) that contains a related set of source files
and a BUILD file. The package also includes any subdirectories, excluding
those that contain their own BUILD file. The package name is the path to the
BUILD file relative to the MODULE.bazel file.
Note that Bazel's package hierarchy is conceptually different from the Java
package hierarchy of your Android App directory where the BUILD file is
located, although the directories may be organized identically.
For the simple Android app in this tutorial, the source files in src/main/
comprise a single Bazel package. A more complex project may have many nested
packages.
Add an android_library rule
A BUILD file contains several different types of declarations for Bazel. The
most important type is the
build rule, which tells
Bazel how to build an intermediate or final software output from a set of source
files or other dependencies. Bazel provides two build rules,
android_library and
android_binary, that you can use to
build an Android app.
For this tutorial, you'll first use the
android_library rule to tell Bazel to build an Android library
module
from the app source code and resource files. You'll then use the
android_binary rule to tell Bazel how to build the Android application package.
Create a new BUILD file in the src/main/java/com/example/bazel directory,
and declare a new android_library target:
src/main/java/com/example/bazel/BUILD:
load("@rules_android//rules:rules.bzl", "android_library")
package(
default_visibility = ["//src:__subpackages__"],
)
android_library(
name = "greeter_activity",
srcs = [
"Greeter.java",
"MainActivity.java",
],
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
)
The android_library build rule contains a set of attributes that specify the
information that Bazel needs to build a library module from the source files.
Note also that the name of the rule is greeter_activity. You'll reference the
rule using this name as a dependency in the android_binary rule.
Add an android_binary rule
The android_binary rule builds
the Android application package (.apk file) for your app.
Create a new BUILD file in the src/main/ directory,
and declare a new android_binary target:
src/main/BUILD:
load("@rules_android//rules:rules.bzl", "android_binary")
android_binary(
name = "app",
manifest = "//src/main/java/com/example/bazel:AndroidManifest.xml",
deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)
Here, the deps attribute references the output of the greeter_activity rule
you added to the BUILD file above. This means that when Bazel builds the
output of this rule it checks first to see if the output of the
greeter_activity library rule has been built and is up-to-date. If not, Bazel
builds it and then uses that output to build the application package file.
Now, save and close the file.
Build the app
Try building the app! Run the following command to build the
android_binary target:
bazel build //src/main:appThe build subcommand instructs Bazel to build the
target that follows. The target is specified as the name of a build rule inside
a BUILD file, with along with the package path relative to your workspace
directory. For this example, the target is app and the package path is
//src/main/.
Note that you can sometimes omit the package path or target name, depending on your current working directory at the command line and the name of the target. For more details about target labels and paths, see Labels.
Bazel will start to build the sample app. During the build process, its output will appear similar to the following:
INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
bazel-bin/src/main/app_deploy.jar
bazel-bin/src/main/app_unsigned.apk
bazel-bin/src/main/app.apk
Locate the build outputs
Bazel puts the outputs of both intermediate and final build operations in a set
of per-user, per-workspace output directories. These directories are symlinked
from the following locations at the top-level of the project directory, where
the MODULE.bazel file is:
bazel-binstores binary executables and other runnable build outputsbazel-genfilesstores intermediary source files that are generated by Bazel rulesbazel-outstores other types of build outputs
Bazel stores the Android .apk file generated using the android_binary rule
in the bazel-bin/src/main directory, where the subdirectory name src/main is
derived from the name of the Bazel package.
At a command prompt, list the contents of this directory and find the app.apk
file:
| OS | Command |
|---|---|
| Linux, macOS | ls bazel-bin/src/main |
| Windows (Command Prompt) | dir bazel-bin\src\main |
| Windows (PowerShell) | ls bazel-bin\src\main |
Run the app
You can now deploy the app to a connected Android device or emulator from the
command line using bazel mobile-install.
This command uses the Android Debug Bridge (adb) to communicate with the
device. You must set up your device to use adb following the instructions in
Android Debug Bridge
before deployment. You can also choose to install the app on the Android emulator
included in Android Studio. Make sure the emulator is running before executing
the command below.
Enter the following:
bazel mobile-install //src/main:app \
--mode=skylark \
--mobile_install_aspect=@rules_android//mobile_install:mi.bzl \
--mobile_install_supported_rules=android_binary \
--java_runtime_version=17 \
--java_language_version=17 \
--tool_java_runtime_version=17 \
--tool_java_language_version=17Note that the extra flags required for mobile-install can be added to your
project's bazelrc file. The mobile-install-specific flags
(--mode, --mobile_install*) will no longer be required starting from
Bazel 8.4.0 and onwards. The various Java flags for language and runtime version
may be required depending on your workspace's Java configuration.
Mobile-install sub-tools require a language and runtime level of 17 or higher.
Now the "Bazel Tutorial App" should install and launch automatically:

Figure 2. Bazel tutorial app.
Congratulations! You have just installed your first Bazel-built Android app.
Further reading
For more details, see these pages:
- Open issues on rules_android GitHub
- More information on mobile-install
- Integrate external dependencies like AppCompat, Guava and JUnit from Maven repositories using rules_jvm_external
- Run Robolectric tests with the robolectric-bazel integration.
- Integrating C and C++ code into your Android app with the NDK
- See more Bazel example projects of:
Happy building!