buildozer: packaging Python apps for Android, iOS and desktop from a single spec file
Generic Python packager for Android and iOS
At a glance
- What is it?
- Buildozer is a CLI packager from the Kivy team that reads a buildozer.spec file and calls python-for-android or kivy-ios to produce device-ready packages. Android SDK and NDK download automatically, but the dependency tree outside Python makes Docker the practical starting point for new projects.
- Who is it for?
- Buildozer suits Python developers using Kivy or another GUI framework who need Android APK output without manually configuring Android Studio and its SDK. For iOS, macOS is required as the build machine; teams without one cannot produce iOS packages through buildozer.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The packaging gap buildozer fills for Python mobile developers
Packaging a Python application for Android or iOS means configuring the Android SDK, the NDK, a specific version of Java, and native build tools before writing any device-specific code. Developers working in Python for mobile deployment have typically done that setup by hand, once per machine, and then hoped the build environment stayed consistent. Buildozer replaces that manual process with a spec file and a command-line interface.
The project is maintained by the Kivy team and delegates to two sibling projects: python-for-android handles Android builds, and kivy-ios handles iOS builds. Buildozer includes features that simplify Kivy app packaging, but the README is explicit that it works independently with other Python GUI frameworks. The practical limit is what the python-for-android recipe catalog covers for native dependencies.
One naming point: the README explicitly flags that buildozer is not related to buildozer.io, an unrelated online build service that shares the name. Anyone searching for this tool may surface both; they have no connection.
How buildozer.spec connects app metadata to platform toolchains
The spec file is the single artifact connecting app configuration to platform-specific toolchain selection. Running `buildozer init` creates a `buildozer.spec` file from the bundled default template in the current directory. That file holds the app title, package name, version, icon paths and the list of Python requirements to include in the build.
For Android, the spec file also records which SDK version and NDK version to target. On the first build, buildozer downloads those versions from Google's servers and caches them in `~/.buildozer`. A clean machine always triggers the full download before the build can start; subsequent builds reuse the cached files already in `~/.buildozer`. Committing the spec file to version control makes toolchain versions reproducible across machines.
For iOS, the spec triggers kivy-ios, which performs an equivalent compilation pass for the Apple toolchain; that path requires macOS, and there is no documented route for iOS builds on Linux through buildozer. Android builds carry no such host-platform restriction.
Running the first Android debug build with the Docker image
The README's installation section warns directly that buildozer has a complicated dependency tree including platform libraries outside of Python, and that many support requests trace to missing dependencies. The Docker image sidesteps that problem by bundling all required tools.
Pre-built images are available from both Docker Hub and the GitHub Container Registry:
docker pull kivy/buildozer:latest
docker pull ghcr.io/kivy/buildozer:latestFor macOS, building the image locally requires an explicit platform flag:
docker buildx build --platform=linux/amd64 --tag=kivy/buildozer .The typical workflow mounts two directories into the container: the project directory and `~/.buildozer` for the SDK and NDK cache. A debug build with both mounts:
docker run --interactive --tty --rm \
--volume "$HOME/.buildozer":/home/user/.buildozer \
--volume "$PWD":/home/user/hostcwd \
kivy/buildozer android debugWithout the `~/.buildozer` volume mount, each container run re-downloads the Android SDK and NDK from scratch. With it, the first run caches the download and subsequent runs reuse it. The output APK lands in the project's `bin/` directory.
What the linux/amd64 flag reveals about Apple Silicon and build time
The macOS Docker build command passes `--platform=linux/amd64`, which instructs Docker Desktop to build an x86_64 image rather than a native ARM image. On Apple Silicon Macs, that x86_64 image runs under emulation. The Docker image includes Java 17 (via openjdk-17-jdk from Ubuntu 26.04) and a full Android build tool suite compiled for x86_64; all of it runs under emulation on an Apple Silicon machine.
The practical cost is longer build times, since every SDK tool invocation runs through the emulation layer and a buildozer Android build calls those tools many times in sequence. On a Linux x86_64 machine, the same Docker image runs natively with no emulation layer.
For teams using Apple Silicon machines, a CI pipeline on Linux x86_64 hardware running the Docker image natively produces faster builds for distribution. The GitHub Action (ArtemSBulgakov/buildozer-action@v1) is a ready-made workflow for that pattern.
Overriding any spec token at build time through environment variables
Any token in `buildozer.spec` can be overridden at build time by setting an environment variable. The naming convention is `$SECTION_TOKEN`: the section name and the token name joined by `_`, with dots in the token name also replaced by `_`.
Three examples from the [app] section of the spec: - `title` is overridden by `$APP_TITLE` - `package.name` is overridden by `$APP_PACKAGE_NAME` - `p4a.source_dir` is overridden by `$APP_P4A_SOURCE_DIR`
This mechanism is most useful in CI pipelines. A spec file in version control holds safe default values; the CI environment injects production app names, keystore paths or signing credentials through environment variables without storing them in the repository. Debug and production builds share one spec file, with the environment controlling what differs between them.
Where the recipe catalog ends and the iOS host requirement begins
Buildozer's Android support depends entirely on the python-for-android recipe catalog. A recipe tells python-for-android how to cross-compile a C or Cython extension for Android's ARM target. Any Python package the app requires that lacks a recipe causes the Android build to fail at compilation. Writing a new recipe is a separate, non-trivial task that falls outside the scope of a buildozer issue.
For iOS, kivy-ios has an equivalent catalog constraint, and the host requirement is absolute: kivy-ios requires macOS, and there is no documented cross-compilation path for iOS on Linux through buildozer.
BeeWare's Briefcase addresses the same packaging problem through a different mechanism. Rather than cross-compiling Python from source using a recipe system, Briefcase packages apps against pre-built Python runtimes for each target platform. For a project whose dependencies all have pre-compiled wheels for the target, Briefcase avoids the recipe-writing step entirely. The trade-off is that Briefcase depends on those wheels existing, while buildozer's recipe system can reach dependencies that publish no wheels at all.
Cadence and legal terms: three years from 1.5.0 to 1.6.0
Release 1.6.0 came on 2026-05-12, following 1.5.0 (2023-01-28) and 1.4.0 (2022-07-20); the last push was on 2026-09-18. The three-year gap between 1.5.0 and 1.6.0 is notable even though commits continued throughout that period, and 1.6.0 appeared only after that long stretch of unpublished development work.
Buildozer is MIT licensed. The setup.py reads the package version from `buildozer/__init__.py` at build time, so pinning a production build to a specific version uses the standard PyPI approach.
Editorial conclusion
Buildozer suits Python developers using Kivy or another GUI framework who need Android APK output without manually configuring Android Studio and its SDK. For iOS, macOS is required as the build machine; teams without one cannot produce iOS packages through buildozer. Before starting, run `buildozer init` and check every native dependency against the python-for-android recipe catalog, since a missing recipe halts the Android build at the compilation step. The Docker image on Docker Hub or GHCR is the most reliable path to a first build on most development machines.
Frequently asked questions
How do I start a new buildozer project?
Run `buildozer init` in the project directory. This creates a `buildozer.spec` file from the default template. Edit it to set the app title, package name and Python requirements before running the first build.
Does buildozer work with Python GUI frameworks other than Kivy?
Yes. Buildozer includes features that simplify Kivy app packaging, but it works independently with other Python GUI frameworks. The practical limit is which native dependencies have recipes in the python-for-android catalog.
Can buildozer produce an iOS package on a Linux machine?
No. The iOS build path uses kivy-ios, which requires macOS. There is no documented route to produce iOS packages from buildozer on a Linux host.
What does the buildozer.spec file contain?
The buildozer.spec file holds the application's configuration: app title, package name, version, icon paths, Python requirements and platform-specific settings such as the Android SDK and NDK versions to use. Running `buildozer init` creates it from the default template.
Does buildozer work on macOS for Android builds?
Yes, through Docker. On Apple Silicon Macs, the Docker image runs under x86_64 emulation because the image targets Linux x86_64, which is slower than building natively on a Linux x86_64 machine. The macOS build command requires `--platform=linux/amd64`.
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/kivy-buildozer)