Skip to content

Build & Ship

This guide shows how to package and distribute a bootstack application.

It is designed to work with the bootstack CLI workflow:

  • bootstack promote --pyinstaller to enable packaging support
  • bootstack build to produce a distributable bundle

What “shipping” means

Shipping typically means producing a single executable bundle (or app folder) that:

  • runs without requiring users to install Python
  • includes your themes, icons, images, and localization resources
  • behaves consistently across systems (fonts, DPI, scaling)

For most desktop apps, the most common approach is PyInstaller.


1) Start a project

Create a project in the style you want:

# Default: a single-view App with assets/, README.md, and a starter view
bootstack start MyApp

# AppShell with sidebar navigation and starter pages
bootstack start MyApp --template appshell

# Pick the starting theme (any value from `bootstack list themes`)
bootstack start MyApp --theme ocean-dark

# Minimal: skip assets/ and README.md
bootstack start MyApp --simple

Packaging support is opt-in — you'll add it via bootstack promote --pyinstaller in step 3 once the app is working.


2) Run locally

Run the app in development mode:

bootstack run

You can also run directly with Python during early prototyping.


3) Promote the project for PyInstaller

Enable PyInstaller support (adds/updates the packaging assets):

bootstack promote --pyinstaller

This step is intentionally opt-in, so a simple local app stays simple.

What this typically does:

  • writes or updates bootstack.toml
  • creates or updates a PyInstaller spec file
  • adds build-related defaults (icon, app name, entrypoint, data files)

4) Build for distribution

Build the distributable bundle:

bootstack build

For a clean rebuild:

bootstack build --clean

Configuration via bootstack.toml

The CLI uses a single source of truth: bootstack.toml.

A typical configuration includes:

  • app metadata (name, version, entrypoint)
  • default container type (GridFrame / PackFrame)
  • theme defaults
  • localization settings
  • build configuration (PyInstaller options, included files)

Including assets

Shipping a desktop app usually requires bundling:

  • icons (app icon + in-app icon packs)
  • themes (custom theme palettes, additional theme files)
  • images (PNG/SVG sources, runtime-generated caches if any)
  • localization (message catalogs / language packs)

If you’re using bootstack’s built-in asset systems, the CLI/build integration should include the relevant folders.


Localization in shipped apps

If you enable i18n with the CLI:

bootstack add i18n

Make sure your build step includes the message catalog assets.

In your UI code, prefer message tokens:

import bootstack as bs

bs.Button(app, text="button.save")

App icon and branding

Most apps should ship with:

  • an application icon (window/taskbar)
  • a brand mark (optional)
  • optional installer metadata (publisher, description)

Your CLI can provide a default icon that users can replace.

If you support per-platform icons:

  • Windows: .ico
  • macOS: .icns
  • Linux: .png (desktop file icon)

Common pitfalls

Missing files at runtime

Symptoms:

  • icons or images disappear
  • theme assets aren’t found
  • localization falls back to raw tokens

Fix:

  • ensure those asset directories are included in the build (spec/data files)
  • keep all runtime assets inside your project, not outside it

DPI and scaling differences

In development, your environment may not match target systems.

  • Test on multiple DPI settings when possible
  • Avoid hardcoded pixel-perfect assumptions

Overriding build behavior

Advanced users may want to edit the spec file directly.

That’s fine — but the recommended path is:

  • keep config in bootstack.toml
  • let bootstack build generate/update the spec when possible

Shipping to macOS

bootstack build produces a .app bundle on macOS via PyInstaller. That bundle runs locally, but it is not yet ready for distribution: modern macOS (10.15+) refuses to launch unsigned, unnotarized apps with the "\"MyApp.app\" is damaged and can't be opened" Gatekeeper dialog.

To ship a .app to other users, you need four additional steps that bootstack intentionally does not perform itself:

  1. Code-sign the bundle with an Apple Developer ID certificate ($99/yr Apple Developer Program membership).
  2. Notarize it via xcrun notarytool submit (Apple's automated malware scan).
  3. Staple the notarization ticket to the bundle so it works offline (xcrun stapler staple).
  4. Package the result into a DMG (or PKG) for distribution.

Apple's notarization toolchain changes often enough that wrapping it into bootstack build would mean ongoing maintenance for a feature only a fraction of users need. The recommended path instead is to hand off to Briefcase (BeeWare), which handles the full chain — signing, notarization, stapling, and DMG creation — across macOS, Linux (.deb/AppImage), and Windows (MSI).

A typical workflow:

# Develop and iterate with bootstack
bootstack start MyApp
bootstack run

# When you're ready to ship to macOS:
pip install briefcase
briefcase create macOS
briefcase build macOS
briefcase package macOS --identity "Developer ID Application: Your Name (TEAMID)"

The Briefcase project layout is independent of the bootstack start layout, so you'll typically point Briefcase at your existing src/ package and reuse your assets. See the Briefcase macOS docs for the full setup.


Next steps