python-for-android: packaging Python apps into APK, AAB and AAR files
Turn your Python application into an Android APK
At a glance
- What is it?
- python-for-android cross-compiles the CPython interpreter and its dependencies for Android, then bundles them with your app code. It is the build backend behind Kivy apps, and it is also the reason a C extension without a recipe will stop your build.
- Who is it for?
- Adopt python-for-android if you ship a Kivy, PySDL2, PySDL3 or WebView app and you need an APK for local testing or an AAB for Google Play. Avoid it if your app depends on a C extension nobody has written a recipe for, or if you expect the build to be a one-command affair on a fresh machine: the README recommends Buildozer precisely because dependency setup is the hard part.
- 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 20 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 September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What python-for-android actually produces, and for whom
python-for-android, usually shortened to p4a, is a development tool that packages Python applications into binaries that run on Android devices. The README lists three output formats, and the distinction matters more than it first appears. An APK is ready to install locally on a device and is what you want for testing and for many third-party app stores, but the README states it is not the format accepted by Google Play Store. An AAB is the format that can be shared on Google Play Store. An AAR is a reusable bundle of resources for other Android projects, which is the option you want if you are embedding a Python component inside a larger native app rather than shipping a standalone product.
The intended audience is Python developers who want their code running on Android without rewriting it in Java or Kotlin. The README is explicit that apps built with the Kivy framework are supported, but that the tool was built to be flexible about backend libraries through something it calls bootstraps. PySDL2, PySDL3 and a WebView backed by a Python web server are named as supported backends. Multiple CPU architectures are supported, which is what lets one build target more than a single class of device.
The honest framing is that p4a is an interpreter packager, not a compiler. The documentation states that the Python code is interpreted on the Android device. That single sentence explains most of the tool's behaviour: startup cost, app size, and the reason pure-Python dependencies tend to just work.
Cross-compiling CPython and the recipe system for C extensions
The mechanism the README describes is cross-compilation followed by bundling. python-for-android works by cross-compiling the Python interpreter and its dependencies for Android devices, and bundling it with the app's Python code and dependencies. The Python code is then interpreted on the Android device. So the artifact you install contains an interpreter built for the target architecture, the standard library, whatever compiled libraries you pulled in, and your own source.
Pure Python packages are handled automatically. The README says the tool automatically supports dependencies on most pure Python packages. For anything else, including packages that depend on C code, a special recipe must be written to support cross-compiling. A recipe is the unit of work that tells the build how to fetch, patch and compile a native dependency for Android. The repository layout reflects this: setup.py walks pythonforandroid/recipes and pythonforandroid/bootstraps to collect patch, diff, Cython, C, header, makefile and jam files into the package data, which is a good indication of what a recipe directory is expected to contain.
The README notes that recipes for many popular libraries, naming numpy and sqlalchemy, ship built in. That is the practical dividing line. If your dependency graph is pure Python plus libraries that already have recipes, the build is mostly a configuration exercise. If it includes a C extension without a recipe, you are writing cross-compilation build logic, and that is a different project from the one you thought you were doing.
Bootstraps are the second axis. They decide what native shell your Python code is embedded in, which is why the same Python app can be a Kivy app, an SDL app or a WebView app depending on the bootstrap chosen.
Installing python-for-android and building a first APK
The README recommends that python-for-android be used via Buildozer, which ensures the correct dependencies are pre-installed and centralizes the configuration. It also states that p4a is not limited to being used with Buildozer. The Makefile in the repository shows the direct route: it creates a virtualenv, installs a pinned Cython and then installs the project in editable mode.
python3 -m venv $(VIRTUAL_ENV)
$(PIP) install Cython==0.29.36
$(PIP) install -e .The Cython pin is not incidental. Several recipes build Cython extensions, and the Makefile fixes the version rather than floating it. If you skip this and install the latest Cython, recipe builds can fail in ways that look like recipe bugs.
The repository also ships a Dockerfile for the same purpose. Its header comment gives the build and run commands, and the Docker path avoids configuring the Android SDK, NDK and a JDK on your host.
docker build --tag=p4a --file Dockerfile .
docker run -it --rm p4a /bin/sh -c '. venv/bin/activate && p4a apk --help'The Dockerfile pins the base image to linux/amd64 on ubuntu:22.04 with a comment explaining why: Google does not provide a linux/arm64 compatible NDK, so the target platform is forced rather than inherited from the host. On an Apple Silicon machine this means emulation, and the build will be slower than the same command on an x86_64 host. The image sets JAVA_HOME to a Java 17 OpenJDK path and defines ANDROID_HOME under the user's home directory.
Once the environment is up, the entry point is the p4a command, and the Dockerfile's own example runs p4a apk --help to confirm the tool is reachable. The Makefile contains a generic test target for building test apps, parameterised by architecture, artifact type, bootstrap, mode and requirements, which is a useful template for the shape of a real invocation:
make ARCH=armeabi-v7a,arm64-v8a ARTIFACT=apk BOOTSTRAP=sdl2 MODE=debug REQUIREMENTS=python testapps-genericThe quickstart guide linked from the README is where the full set of options lives. The README itself does not enumerate the flags of p4a apk, so treat the online documentation as the reference rather than guessing at option names.
Where python-for-android stops being the right tool
The clearest limitation is the recipe requirement. The README frames it plainly: for packages that depend on C code, a special recipe must be written to support cross-compiling. That is not a configuration flag you can flip. It means writing and maintaining build instructions for a library against the Android NDK, and doing it again when the library or the NDK moves. A team that picks p4a for an app whose dependency tree is mostly compiled extensions is signing up for ongoing work that has nothing to do with their actual product.
A second constraint is the packaging format boundary. The README states that APK files are used by many app stores but not Google Play Store, and that AAB files are the ones that can be shared there. If your distribution plan is Google Play, the APK you build for local testing is not the artifact you ship, and the two outputs come from the same build configuration. Planning around a single APK is a mistake here.
Third, this is an interpreter bundle. The README says the Python code is interpreted on the device, which means the interpreter and its dependencies are part of your download. That is a size and startup cost you accept in exchange for not rewriting in Kotlin. For a small utility that would be a few hundred kilobytes as a native app, the trade is poor.
Finally, the README does not document rollback, and it does not describe a reproducible lockfile for the Android SDK and NDK versions a given build used. The Makefile exposes ANDROID_SDK_HOME, ANDROID_NDK_HOME and ANDROID_NDK_HOME_LEGACY as overridable variables, which tells you the paths are configurable but not that a build is pinned. Treat environment pinning as your responsibility.
Buildozer, and what changes when you use it
The README's recommendation is to use p4a through Buildozer, and the difference is one of scope rather than capability. Buildozer wraps the p4a invocation and manages the surrounding environment: it ensures the correct dependencies are pre-installed and centralizes the configuration. In practice that means you describe your app in a buildozer.spec file and run a single command, instead of maintaining a virtualenv, an Android SDK, an NDK and a JDK by hand.
Calling p4a directly is still supported, and the Makefile and Dockerfile in this repository exist for exactly that workflow. The trade is control against setup burden. Direct invocation lets you pass architecture, bootstrap, mode and requirements per build, as the testapps-generic target demonstrates, and lets you drive the tool from your own CI without adopting another tool's configuration format. It also means you own every environment variable and every version pin.
A reasonable split: use Buildozer if you are shipping one app and want the documented path, and drive p4a directly if you are building artifacts as part of a larger pipeline or need to control the bootstrap and architecture matrix explicitly. Note that the README does not claim p4a requires Buildozer, only that Buildozer is recommended, so direct use is a supported posture rather than a workaround.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-09-10, which is recent. The release history is uneven: v2026.05.09 was published on 2026-05-10, the previous release v2024.01.21 on 2024-01-23, and v2023.09.16 on 2023-09-17. That is a gap of roughly sixteen months between the 2024 and 2026 releases. Development activity on the develop branch and tagged releases are not the same signal, and anyone pinning to a release tag should look at the changelog rather than assuming the cadence is regular.
The practical upgrade cost sits in the recipes and the toolchain. Recipes carry patches and diffs against specific library versions, and setup.py collects those patch and diff files as package data, so a recipe update can invalidate patches you have written yourself. The Makefile includes a rebuild_updated_recipes target that installs Rust via rustup before running ci/rebuild_updated_recipes.py, which tells you that some recipes involve a Rust toolchain in addition to the NDK. Budget for toolchain churn, not just source changes.
Licensing is MIT, per the repository's LICENSE file and the project metadata. MIT is permissive and imposes no copyleft obligation on your application code. That said, the licence covers python-for-android itself, not the libraries you bundle into your APK. CPython, the Android NDK, and every recipe you pull in carry their own terms, and some of those are not permissive. Check the licences of your bundled dependencies separately. This is not legal advice; if your distribution plan depends on the answer, get it from someone qualified.
Editorial conclusion
Adopt python-for-android if you ship a Kivy, PySDL2, PySDL3 or WebView app and you need an APK for local testing or an AAB for Google Play. Avoid it if your app depends on a C extension nobody has written a recipe for, or if you expect the build to be a one-command affair on a fresh machine: the README recommends Buildozer precisely because dependency setup is the hard part. Before committing, verify that every non-pure-Python dependency you need has a recipe in pythonforandroid/recipes, and confirm which bootstrap your UI framework requires.
Frequently asked questions
What is python-for-android?
It is a development tool that packages Python apps into binaries that can run on Android devices. It produces APK, AAB and AAR files, and works by cross-compiling the Python interpreter and its dependencies for Android, then bundling them with your app code.
How do I install python-for-android?
The README recommends using it via Buildozer, which ensures the correct dependencies are pre-installed. The repository Makefile shows the direct route: create a virtualenv, install Cython==0.29.36, then install the project in editable mode. A Dockerfile is also provided for a preconfigured build environment.
How do I use python-for-android for app development?
You configure a bootstrap and a set of requirements, then invoke the p4a command to produce an artifact. The README points to the online quickstart guide for the full option set, and the Makefile's testapps-generic target shows the shape of an invocation with ARCH, ARTIFACT, BOOTSTRAP, MODE and REQUIREMENTS.
Can you use Python on Android?
Yes. python-for-android cross-compiles the Python interpreter for Android and bundles it with your app code, and the Python code is then interpreted on the device. The README lists Kivy, PySDL2, PySDL3 and a WebView with a Python web server as supported backends.
How do I use python-for-android?
The README recommends driving it through Buildozer, which pre-installs the correct dependencies and centralizes configuration. Direct use is also supported: the Dockerfile header shows running p4a apk --help inside the container to confirm the tool is reachable.
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-python-for-android)