Skip to main content

django-binary-builder

Build Django projects as installable desktop applications for Windows.

django-binary-builder turns any Django project into a standalone Setup.exe in one command. The packaged application ships a portable Python runtime with your project and every dependency installed by pip — no code is frozen, so any library that works in your development virtual environment (including native/C-extension packages) works in the packaged application. Size is traded for compatibility on purpose.

When the user starts the installed app, Django is served by waitress on a loopback port in the background and the application opens in a native desktop window (via pywebview); closing the window shuts the server down and exits the process. If pywebview is unavailable, the default browser is used as a fallback.

Quick start

1. Check the prerequisites

  • Python 3.10+ — any full CPython build (the python.org installer, uv, ...). The Microsoft Store Python cannot be packaged.
  • Django 5.0 or newer project with WSGI_APPLICATION configured (the startproject default).
  • Windows 10 or 11 — installers must be built on a Windows host.
  • Inno Setup 7 — only needed for the final Setup.exe; skip it with --skip-installer while iterating.
  • Internet access on the build machine the first time dependencies are installed into the runtime (pip uses its normal cache afterwards).

Always build from the virtual environment you develop in: it defines both the Python runtime that gets copied and the fallback dependency list.

2. Install and register the app

Use whichever workflow you already use for the project — plain pip or uv. Both install the library into the project's virtual environment.

With pip (run inside your project's virtual environment):

pip install django-binary-builder

With uv:

uv add django-binary-builder

Then register the app:

# settings.py
INSTALLED_APPS = [
    # ... your apps
    "django_binary_builder",
]

3. (Optional) add the five-key setting

Every key is optional — with no setting at all, the project folder name becomes the application name:

# settings.py
from pathlib import Path

DJANGO_BINARY_BUILDER = {
    "NAME": "Example Project",
    "VERSION": "0.1.1",
    "PUBLISHER": "Example Company",
    "EXECUTABLE_NAME": "example-project",
    "ICON": BASE_DIR / "assets" / "icon.ico",
}

4. Build

Run the build from the same (activated) virtual environment you develop in.

With pip (virtual environment activated):

python manage.py binary windows

With uv:

uv run python manage.py binary windows

The installer is written to:

release/windows/<executable-name>-<version>-Setup.exe

Users install it per-user (no admin rights needed), get a desktop and start-menu shortcut, and your app runs completely offline.

CLI

python manage.py binary PLATFORM [OPTIONS]

PLATFORM accepts windows (implemented), or linux / macos (reserved, not implemented yet). uv users prefix the command with uv run (for example uv run python manage.py binary windows) so it executes inside the project environment.

Option Behaviour
--check Run preflight checks only; create no files.
--skip-installer Build the runnable application bundle without requiring Inno Setup.
--output PATH Override the output directory (default:release/).

The complete configuration

DJANGO_BINARY_BUILDER is the entire configuration surface — five optional keys:

Key Meaning Default when omitted
NAME Display name (window title, installer name, start menu) the project folder name
VERSION Application version "0.1.0"
PUBLISHER Publisher name (installer metadata, data directory) NAME
EXECUTABLE_NAME Safe name for the.exe file NAME, converted to a safe file name
ICON Application icon, must be an.ico file no custom icon

Unknown keys are ignored with a warning, so typos surface without blocking builds.

How the build works

Read the 5-key DJANGO_BINARY_BUILDER setting
→ Bundle .env as-is (the process environment wins at runtime)
→ Resolve dependencies: requirements.txt → pyproject.toml → pip freeze
→ Resolve the Python pin (.python-version)
→ Copy the current CPython installation into bundle/runtime
→ pip install every dependency into the portable runtime
→ Copy the project + the library, collect static files, generate the launcher
→ Build a dependency-free entry executable (PyInstaller stub)
→ Package everything with Inno Setup into a Setup.exe

The entry executable is an intentionally dependency-free PyInstaller stub: its only job is to start runtime\pythonw.exe app\launcher.py and forward the exit code. Your Django code is never frozen — that is what makes any pip-installable library work out of the box.

Dependency resolution

  1. If requirements.txt exists in the project root, it is used as-is.
  2. Otherwise, if pyproject.toml exists, its [project] dependencies are used.
  3. Otherwise requirements.txt is generated from the current environment (the equivalent of pip freeze, with django-binary-builder, pip, setuptools and wheel excluded) and written into the project root.

The launcher's runtime dependencies (waitress, pywebview, python-dotenv) are appended automatically when missing.

.python-version

The build generates .python-version in the project root containing the current interpreter's version (for example 3.14). If the file already exists it is used as-is, and the build fails when the current interpreter does not match it — activate the right virtual environment to build reproducible bundles.

Bundle layout

<install dir>                        %LOCALAPPDATA%\Programs\Example Project
├── example-project.exe              entry stub (starts the runtime)
├── _internal/                       PyInstaller support files for the stub
├── runtime/                         complete portable CPython + site-packages
└── app/                             your project
    ├── manage.py, myproject/, ...
    ├── django_binary_builder/       the library itself (bundled import)
    ├── staticfiles/                 collected by the build
    ├── .env                         bundled when present
    ├── db.sqlite3                   bundled when present (first-run seed)
    └── launcher.py                  generated entry point

Runtime behaviour

  • Server: waitress serves the WSGI application on 127.0.0.1 (first free port from 8765) in a background thread.
  • Window: a 1200×800 pywebview window titled NAME; the default browser is the fallback. Closing the window exits the app.
  • Environment: the bundled .env is applied at startup with python-dotenv; variables already present in the process environment always win, so deployments can override anything — including DJANGO_SETTINGS_MODULE.
  • Database:
    • SQLite databases are relocated on first start to a writable per-user data directory, seeded from the bundled copy and never overwritten on upgrades:

      %LOCALAPPDATA%/<Publisher>/<Name>/     (names sanitized: spaces → dashes)
      ├── data/db.sqlite3
      ├── logs/application.log
      ├── logs/startup.log
      └── media/
      

      Override the root with the DJANGO_BINARY_DATA_DIR environment variable. Delete db.sqlite3 from the project before building to ship an empty database.

    • External databases (PostgreSQL, MySQL, ...) keep the project's DATABASES settings — install the driver in your build environment (for example pip install "psycopg[binary]" or uv add "psycopg[binary]") so it lands in the packaged runtime.

  • Migrations run automatically on every startup.
  • Initial admin: when django.contrib.auth is installed and no superuser exists, one is created with username admin and the password from DJANGO_BINARY_ADMIN_PASSWORD (default admin1234; DJANGO_BINARY_ADMIN_USERNAME overrides the username). Change it immediately after the first login.
  • Static files: /static/ is served from the bundled staticfiles/ directory — no web server or whitenoise configuration needed.
  • Media files: served at the MEDIA_URL prefix when it is a real sub-path (for example /media/). Django 6.1 defaults MEDIA_URL to /, which is deliberately not mounted because it would shadow every route — set MEDIA_URL = "/media/" to enable media serving.
  • 127.0.0.1 and localhost are appended to ALLOWED_HOSTS automatically.

Security notes

  • A bundled .env or SQLite database can be extracted by anyone with file access — never package real secrets. Provide sensitive values through the environment on the deployment machine instead.
  • The initial administrator uses a publicly documented default password; it is only a convenience for first-run setups.

Troubleshooting

  • pins Python 3.x but the current interpreter is ... — the .python-version file records the build Python; activate a matching virtual environment (or update the file) and rebuild.
  • pip install failed inside the portable runtime — check internet access and the dependency specifiers; pip's output is printed during the build.
  • The Microsoft Store Python cannot be packaged — install Python from python.org or via uv and rebuild from its virtual environment.
  • Inno Setup 7 was not found — install Inno Setup 7, add ISCC.exe to PATH, set the DJANGO_BINARY_INNO_COMPILER environment variable, or build with --skip-installer.
  • The installed app does not start — check %LOCALAPPDATA%\<Publisher>\<Name>\logs\application.log and startup.log; all output goes there because the packaged app has no console.
  • Port 8765 is busy — the launcher automatically picks the next available port.

Known limitations

  • Windows only (linux/macos targets are reserved but not implemented); no cross-compilation.
  • WSGI only — no ASGI, Django Channels or WebSocket support.
  • No Celery worker/beat, no bundled or auto-installed database servers.
  • No Windows Service support, no automatic updater, no code signing.
  • The bundle is large (hundreds of MB) by design: the complete Python runtime is shipped inside the installer.

Example

See the examples directory for a complete project demonstrating the five-key configuration, a custom icon, a bundled SQLite database and a requirements.txt.

Release files for django-binary-builder 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-binary-builder 0.3.2
File Size Uploaded
django_binary_builder-0.3.2.tar.gz 23.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-binary-builder 0.3.2
File Interpreter ABI Platform
django_binary_builder-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 56.0 kB

Release files / django_binary_builder-0.3.2.tar.gz

Download URL django_binary_builder-0.3.2.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
eecb415ce058fb3c702e8262573b2ec9b7c7dedcccabe024d9ea0ca27f09e7de
BLAKE2b-256 checksum
How to use checksums
8fb446dc0fbd3ad466937a9faf69fc2c695b406fe3dcece4584acd0f534cc683
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / django_binary_builder-0.3.2-py3-none-any.whl

Download URL django_binary_builder-0.3.2-py3-none-any.whl
Size 32.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca53ed02ae76045f12ad3c341c0f5742a6325dded6196121fb93fd5b2eb8ff60
BLAKE2b-256 checksum
How to use checksums
eaabce827f9ccbe2fd2781a0cb6421b9888c08dbd9bce1da5b24eec3b844b797
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.3.3

2 release files

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page