Turn your Duck Framework web app into a real Android app.
Website · Documentation · Native Actions · Install Dependencies · Termux Guide · Report a bug
📖 What is Duck Native?
You already have a web app built with Duck Framework. Duck Native wraps it in an Android app, so people can install it from an APK or the Play Store like any other app.
You do not need to write Kotlin or Java. You edit one Python file
(native/config.py) and run one command.
📚 New here? Read the guides: 📱 Native Actions (use the phone's features from your pages), 🧩 Native Widgets (use real Android widgets from Python, like a date picker or bottom sheet), 📦 Installing Dependencies (set up Gradle and Kotlin with
duck sync) and 🤖 Building on Termux (build apps right on your phone).
📋 Table of contents
- What you need
- Install and Setup
- Quick start
- Guides
- Commands
- Settings
- Where is my app?
- Troubleshooting
- Contributing
✅ What you need
| Need | Why | Needed for apk command? |
|---|---|---|
| Python 3.10 or newer | Runs Duck Native | Yes |
| A Duck Framework project | The app you want to wrap | Yes |
| JDK 17 | Runs Gradle | No |
| Android SDK | Builds the app | No |
| Gradle 8.9 or newer | Builds the app | No |
💡 Just want to try your app on a phone quickly? Skip the last three rows and use
duck native apk.📦 Need Gradle or Kotlin? Run
duck sync --with-dev, see Installing Dependencies.🤖 Developing on a phone? Follow the Termux guide.
📦 Install and Setup
pip install duck-native
Apply settings
You must enable native in your settings file:
NATIVE_ENABLED = True
The above line enable Native capabilities for your app and it requires duck-native to be installed.
🚀 Quick start
Run these inside your Duck project folder.
1. Create the config
duck native init
This creates native/config.py.
2. Edit it
Open native/config.py and change at least these two lines:
APP_NAME = "My Duck App"
PACKAGE_NAME = "com.yourname.myapp"
3. Build
duck native build
4. Install the app
Copy build/app-debug.apk to your phone and open it, or plug your phone in and
run adb install -r build/app-debug.apk.
That's it! 🎉
📚 Guides
| Guide | What you will learn |
|---|---|
| 📱 Native Actions | Show toasts, vibrate, copy text and share from your pages, and write your own Kotlin actions. |
| 📦 Installing Dependencies | Install Gradle, Kotlin and other system tools with one command, duck sync. |
| 🤖 Building on Termux | Set up the SDK, Java and aapt2 to build apps on an Android phone. |
🧰 Commands
duck nativeandduck-nativeare the same command. We suggestduck nativeas the base command, and the examples here use it. Useduck-nativeif you prefer one word, orpython -m duck_native.
| Command | What it does |
|---|---|
duck native init |
Creates native/config.py in your project. Add --force to overwrite. |
duck native check |
Checks your config and shows any problems. Builds nothing. |
duck native build |
Builds your app. Debug builds make an APK. |
duck native build --apk |
Builds a release APK instead of a bundle (when DEBUG = False). |
duck native apk |
Gets a ready-made debug APK, with no Gradle or SDK needed. |
Every command takes an optional project folder, for example
duck native build ../my-app.
⚡ Get a ready-made debug APK
duck native apk # copies app-debug.apk into your build folder
duck native apk --install # also installs it on a connected phone
duck native apk --output ~/Desktop/test.apk
This APK is the same for everyone, so settings like the app name, icon and
permissions are not applied. Use duck native build when you need them.
🔨 What build does
You will see each step in the terminal:
- Prepare: copies the Android project into
build/android. - Generate: creates your icons, splash screen and manifest.
- Build: runs Gradle on the copy.
- Collect: copies the finished APK or AAB into
build/.
If the build fails, Duck Native prints suggestions based on the error.
⚙️ Settings
All settings live in native/config.py. The common ones:
| Setting | Example | What it does |
|---|---|---|
APP_NAME |
"My Duck App" |
Name shown under the app icon. |
PACKAGE_NAME |
"com.yourname.myapp" |
Unique app ID. Pick it once and keep it. |
VERSION |
"1.0.0" |
Version people see. |
VERSION_CODE |
1 |
Whole number. Raise it for every update. |
PERMISSIONS |
["android.permission.INTERNET"] |
Only list what you need. |
ICON |
"assets/icon.png" |
App icon. Use a square PNG. |
SPLASH_IMAGE |
"assets/splash.png" |
Image shown while the app starts. |
ORIENTATION |
"portrait" |
portrait, landscape or unspecified. |
FULLSCREEN |
False |
Hide the status and navigation bars. |
DEBUG |
True |
True builds a debug APK. False builds a release. |
COMPILE_SDK |
36 |
Lower this if the build can't load android.jar. |
SIGNING_KEYSTORE |
"my.keystore" |
Needed to sign release builds. |
The generated file has a comment above every setting explaining it.
📁 Where is my app?
Everything ends up in the build/ folder of your project:
build/
├── app-debug.apk ← debug build
├── app-release.aab ← release bundle (Play Store)
├── android/ ← working copy of the Android project
└── generated/ ← icons, splash and manifest made for you
🩹 Troubleshooting
| Problem | Fix |
|---|---|
Gradle was not found |
Install Gradle 8.9 or newer. |
SDK location not found |
Set the ANDROID_HOME environment variable to your SDK folder. |
failed to load include path ... android.jar |
Add COMPILE_SDK = 34 to native/config.py. Common on Termux, see the Termux guide. |
Failed to install the following Android SDK packages |
Run sdkmanager --licenses and accept everything. |
Pillow is required |
Run pip install pillow. |
Release APK says unsigned |
Set SIGNING_KEYSTORE and SIGNING_KEY_ALIAS, plus the DUCK_KEYSTORE_PASSWORD and DUCK_KEY_PASSWORD environment variables. |
Still stuck? Open an issue and paste the output of the failed command.
🤝 Contributing
Contributions are welcome! See the contribution guide or open an issue.
📄 License
Released under the BSD 3-Clause License.
Metadata
Release files for duck-native 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| duck_native-1.0.0.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| duck_native-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.2 MB
Release files / duck_native-1.0.0.tar.gz
| Download URL | duck_native-1.0.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7df03cd68e53753bb7427901edb435925ce6fe7e636ba7490ead0f9b4ba03ad8
|
|
BLAKE2b-256 checksum How to use checksums |
0335af40fd2f134782c234e9fa42395d4a7e619e98439d1167e6ecd7d382bda0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / duck_native-1.0.0-py3-none-any.whl
| Download URL | duck_native-1.0.0-py3-none-any.whl |
|---|---|
| Size | 1.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
21e6d333730f2b88dca361475f7131b02a7dd2a7ca4fe5857d2faa4340218ad7
|
|
BLAKE2b-256 checksum How to use checksums |
97e7a799da80f8d74151d5f1c7909d8be2fff17ebbb97421a903e2c6cfe58eb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency log