Python Briefcase Native Apps — Core Concepts
What Briefcase solves
Most Python packaging tools (PyInstaller, cx_Freeze) produce standalone executables but not true platform-native packages. Briefcase goes further — it creates MSI installers, macOS app bundles, Flatpaks, APKs, and Xcode projects that follow each platform’s distribution conventions.
The BeeWare ecosystem
Briefcase is one piece of a larger toolkit:
- Toga — a native widget toolkit (uses Cocoa on macOS, GTK on Linux, Winforms on Windows, Android views on Android)
- Briefcase — project scaffolding, building, and packaging
- Rubicon — bridges to Objective-C (macOS/iOS) and Java (Android) runtimes
You can use Briefcase with any GUI framework (Tkinter, PyQt, Kivy), but it works best with Toga for truly native-looking apps.
Creating a new project
pip install briefcase
briefcase new
The interactive wizard asks for app name, description, author, license, and GUI toolkit. It generates a project structure:
myapp/
├── pyproject.toml # project configuration
├── src/
│ └── myapp/
│ ├── __init__.py
│ ├── __main__.py
│ ├── app.py # main application code
│ └── resources/
│ └── icon.png
The development workflow
Briefcase provides a consistent set of commands:
| Command | Purpose |
|---|---|
briefcase dev | Run in development mode (no packaging) |
briefcase create | Scaffold platform-specific project files |
briefcase build | Compile and prepare the platform build |
briefcase run | Build and launch the app |
briefcase package | Create distributable installer |
briefcase update | Sync code changes into existing build |
The typical flow: develop with briefcase dev, then briefcase run to test the native build, and briefcase package for distribution.
Configuration in pyproject.toml
[tool.briefcase]
project_name = "My App"
bundle = "com.example"
version = "1.0.0"
requires = ["toga>=0.4.0", "httpx"]
[tool.briefcase.app.myapp]
formal_name = "My App"
description = "A sample Toga application"
sources = ["src/myapp"]
[tool.briefcase.app.myapp.macOS]
requires = ["toga-cocoa>=0.4.0"]
[tool.briefcase.app.myapp.windows]
requires = ["toga-winforms>=0.4.0"]
[tool.briefcase.app.myapp.linux]
requires = ["toga-gtk>=0.4.0"]
system_requires = ["libgirepository1.0-dev"]
[tool.briefcase.app.myapp.android]
requires = ["toga-android>=0.4.0"]
[tool.briefcase.app.myapp.iOS]
requires = ["toga-iOS>=0.4.0"]
Platform-specific sections let you add OS-specific dependencies, permissions, and build settings.
Platform outputs
| Platform | Output format | Distribution method |
|---|---|---|
| macOS | .app bundle, .dmg | Direct download, notarization for Gatekeeper |
| Windows | MSI installer | Direct download, Windows Store (possible) |
| Linux | Flatpak, AppImage, Snap | Flathub, direct download |
| Android | APK / AAB | Google Play Store, sideloading |
| iOS | Xcode project | App Store via Xcode |
| Web | Static files | Browser deployment (experimental) |
A minimal Toga application
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
class MyApp(toga.App):
def startup(self):
main_box = toga.Box(style=Pack(direction=COLUMN, padding=10))
name_input = toga.TextInput(placeholder="Your name",
style=Pack(flex=1))
button = toga.Button("Say Hello",
on_press=lambda w: self.greet(name_input.value),
style=Pack(padding_top=10))
self.label = toga.Label("", style=Pack(padding_top=10))
main_box.add(name_input, button, self.label)
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_box
self.main_window.show()
def greet(self, name):
self.label.text = f"Hello, {name}!"
def main():
return MyApp()
This renders with native Cocoa widgets on macOS, WinForms on Windows, and GTK on Linux — the same code, truly native appearance.
Common misconception
“Briefcase is just another PyInstaller alternative.”
PyInstaller creates standalone executables. Briefcase creates complete platform-native packages — MSI installers, app bundles with proper Info.plist, Flatpaks with desktop integration, and APKs with Android manifests. It handles icons, splash screens, permissions, and signing — the full distribution story, not just the executable.
One thing to remember: Briefcase is a complete app lifecycle tool — from project scaffolding through native packaging — that makes Python apps first-class citizens on every major platform.
See Also
- Python Appimage Distribution An AppImage is like a portable app on a USB stick — download one file, double-click it, and your Python program runs on any Linux computer without installing anything.
- Python Flatpak Packaging Flatpak wraps your Python app in a safe bubble that works on every Linux system — like a snow globe that keeps your program perfect inside.
- Python Mypyc Compilation Your type hints are not just for documentation — mypyc turns them into speed boosts by compiling typed Python into fast C extensions.
- Python Nuitka Compilation What if your Python code could run as fast as a race car instead of a bicycle? Nuitka translates Python into C to make that happen.
- Python Pex Executables Imagine zipping your entire Python project into a single magic file that runs anywhere Python lives — that's what PEX does.