Configuration
All configuration lives in your app’s pyproject.toml under
[tool.pyappdist]. pyproject.toml is the single source of truth.
It has three parts:
[tool.pyappdist] — app-level settings (the runtime version, display name, dependency manager).
[[tool.pyappdist.launchers]] — one entry per executable to produce.
[[tool.pyappdist.targets]] — one entry per output package. Format-specific keys are documented on each format’s page (see Output formats).
[tool.pyappdist]
python(required)Python version for the bundled runtime, as
X.YorX.Y.Z(e.g."3.12").nameDisplay name of the app. Defaults to
[project].name.versionProduct version. Defaults to
[project].version(then"0.0.0").managerPackage manager used to pin dependencies:
"uv","poetry","pipenv","pdm", or"requirements.txt". Auto-detected from the lockfile when omitted. See Dependency resolution.identifierCFBundleIdentifier in reverse-DNS form (e.g.
"com.example.myapp"). Required when any target usesformat = "macapp"or"dmg"; unused by the other formats. With multiple launchers each bundle derives<identifier>.<launcher>.
[tool.pyappdist]
name = "My App"
python = "3.12"
# identifier = "com.example.myapp" # required for macapp/dmg targets
[[tool.pyappdist.launchers]]
An array of tables — one entry per executable to produce. At least one is required
to build launchers. The same launcher set is used for every target; how a launcher
is realized depends on the format (a compiled .exe on Windows, a relocatable
shell wrapper on Linux/macOS).
name(required)Output executable name without extension (
"myapp"→myapp.exeon Windows).entry(required)Entry point, in one of two forms:
"module:callable"— importcallablefrommoduleand invoke it with no arguments; its return value becomes the process exit code."module.path"(no colon) — run the module aspython -m module.path(executed with__name__ == "__main__"). Use this for apps whose startup lives under anif __name__ == "__main__":guard (e.g. NiceGUI).
guitruebuilds a windowed launcher usingpythonw.exe(no console) on Windows. Defaults tofalse(console,python.exe). Ignored on Linux/macOS.iconA per-OS table of icon paths (relative to the project directory); each key is optional:
windows— an.ico, embedded in the.exe.macos— a.png(ideally ≥1024×1024), converted to the.app’s.icns.linux— an image (.pngrecommended) used for the.desktopentry.
A plain string is not accepted — give the format each platform needs. An omitted key means that platform gets no icon (macOS falls back to a generated placeholder).
argsFixed arguments as a single string, prepended to the program’s argv.
[[tool.pyappdist.launchers]]
name = "myapp"
entry = "myapp:main"
gui = false
# args = "--profile default"
[[tool.pyappdist.launchers]]
name = "myapp-gui"
entry = "myapp.gui:main"
gui = true
icon = { windows = "assets/app.ico", macos = "assets/app.png", linux = "assets/app.png" }
[[tool.pyappdist.targets]]
An array of tables — one entry per output package. At least one target is required.
The individual pipeline stages apply to all targets by default; pyappdist
build builds the sole target, or the ones you name: pyappdist build <name>
<name> (see Command-line interface).
These keys are common to every format; the format-specific keys live on the format pages.
platform(required)Distribution platform (see Platform values).
format(required)Output package. Must match the platform’s OS:
"msi"or"msix"on Windows,"linux"on Linux, and on macOS either"macos"(a portable.runinstaller, like Linux) or"macapp"/"dmg"(a.appbundle, optionally inside a.dmg, for GUI distribution). A mismatch (e.g."msi"withlinux-x86_64) is rejected at load. See Output formats.name(required)Label used to select this target on the command line and as its output subdirectory (
appdist/<name>/). Must be unique across targets.extras(optional)A list of
[project.optional-dependencies]extras to bundle for this target, passed through to the lockfile export (e.g. uv’s--extra). Defaults to an empty list, i.e. production dependencies only (dev excluded). See Dependency resolution.
Platform values
windows-x86_64Triple
x86_64-pc-windows-msvc· OS windows · formatmsi/msix.linux-x86_64Triple
x86_64-unknown-linux-gnu· OS linux · formatlinux.macos-aarch64Triple
aarch64-apple-darwin· OS macos · formatmacos/macapp/dmg.macos-x86_64Triple
x86_64-apple-darwin· OS macos · formatmacos/macapp/dmg.
Output formats
Each format has its own configuration keys, build requirements, and install behavior:
- msi
.msiinstaller + portable.zip.- msix
.msixpackage (Store / sideloading).- linux
.tar.{gz,bz2,xz}+ self-extracting.run.- macos
.tar.{gz,bz2,xz}+ self-extracting.run.- macapp / dmg
A macOS
.appbundle (macapp), optionally wrapped in a.dmg(dmg); Developer-ID-signed and notarized when configured.
A single project can declare several targets and produce all of these at once:
[[tool.pyappdist.targets]] # an MSI
name = "windows"
platform = "windows-x86_64"
format = "msi"
manufacturer = "Example Inc."
[[tool.pyappdist.targets]] # a Linux .tar.xz + .run installer
name = "linux"
platform = "linux-x86_64"
format = "linux"
[[tool.pyappdist.targets]] # a macOS .tar.gz + .run installer
name = "macos-arm"
platform = "macos-aarch64" # or "macos-x86_64" for Intel
format = "macos"