Skip to content

Distributing macOS .app Bundles

This guide covers how a protected macOS application reaches your customer and runs, from the download all the way to launch.


A .app is a folder, so it travels as a .app.zip

A macOS .app is a bundle: a directory that Finder treats as a single application. A download is a single file, not a folder, so PyLocket delivers a protected .app as a .app.zip. This is the standard way macOS apps are distributed outside the App Store.

When the customer downloads it:

  • Most browsers (Safari, Chrome) expand the .app.zip automatically into the runnable .app.
  • If a browser does not auto-expand it, one double-click in Finder runs Archive Utility and produces the .app.
  • The PyLocket Installer and Hub download and expand it for the customer with no manual step at all (see PyLocket Installer and Hub).

Do not rename the .app.zip to .app

A .app-named file that is actually a zip will not launch, because macOS expects anything named .app to be a folder. Let the customer (or the Installer) unzip it so they get a real .app folder.


Uploading your build for protection

Upload the .app bundle itself (PyLocket zips it for you internally):

  • PyInstaller windowed GUI app: build with --windowed, then upload the resulting YourApp.app.
  • Briefcase: upload the .app it produces directly.
  • cx_Freeze / onedir: zip the output directory and upload the .zip.

PyLocket protects the Python bytecode inside the bundle and returns a protected .app (delivered as .app.zip) that runs the same way the original did.


Running the app on the customer's Mac

Because the protected .app is downloaded outside the browser when delivered by the PyLocket Installer or Hub, it launches cleanly. If the customer downloads the .app.zip directly through a browser, macOS may apply its standard quarantine to a file from the internet and show a Gatekeeper prompt the first time.

  • If you signed and notarized the app with your own Apple Developer ID (see Code Signing), Gatekeeper accepts it with no warning.
  • If the app is unsigned, the customer right-clicks the app and chooses Open once to confirm; afterward it launches normally.

For the smoothest, no-warning, no-manual-step experience, sign and notarize the app and deliver it through the PyLocket Installer or Hub.


Optional: sign with your own Apple Developer ID

Signing and notarizing is what removes Gatekeeper friction for your customers. PyLocket lays out the protected .app so it is ready to sign with your certificate. See Code Signing for the full walkthrough, including the one entitlement you must add because PyLocket's embedded runtime is signed by a different team than yours.

Once you have a signed copy, you can upload it back to PyLocket using Replace with Signed Package so the signed version is what your customers download. See Replace with Signed Package.


Topic Link
Sign and notarize your app Code Signing
Upload your signed copy Replace with Signed Package
Zero-manual-step install PyLocket Installer and Hub
Multi-OS publishing Multi-OS Publishing