Reference

AppBundler is structured around two concepts: a product spec, which describes how to build a Julia application, and a bundle format, which describes how to package it for distribution on a target platform. These are combined through the bundle function:

bundle(spec, format, destination; password = "")

This is also the function exposed to the command-line API, where command-line parameters configure the spec and format fields.

Product Specs

A product spec defines how the application is compiled or staged. There are two kinds:

spec = JuliaImgBundle(project; kwargs...)  # stages a self-contained Julia image
spec = JuliaCBundle(project; kwargs...)    # compiles a native executable via juliac

Both specs can be staged directly into a directory for inspection before packaging via stage(spec, destination). For JuliaImgBundle, staging is platform-agnostic as long as compilation is not required — cross-platform staging is possible by setting precompile=false and sysimg_packages = [], with the target platform specified via the platform keyword (defaults to HostPlatform()). For JuliaCBundle, the platform is fixed to the host, as determined by the juliac executable on PATH.

Bundle Formats

A bundle format defines the packaging target. The three supported formats are DMG (macOS), MSIX (Windows), and Snap (Linux). They are instantiated from a project directory:

dmg  = DMG(project; arch = Sys.ARCH, kwargs...)
msix = MSIX(project; arch = Sys.ARCH, kwargs...)
snap = Snap(project; arch = Sys.ARCH, kwargs...)

Each format reads configuration file overrides from the corresponding project/meta/<format> directory and carries architecture information that determines the destination platform. Bundle formats can also be staged independently via stage(format, destination) to produce the directory structure before compression and signing.

Low-Level Bundle API

For packaging non-Julia applications, or when you need full control over what goes into the bundle, the lower-level bundle do-block API can be used directly:

bundle(format, destination; password = "") do staging_dir
    # copy or compile application files into staging_dir
end

The password argument is the certificate password used to decrypt the signing certificate and perform code signing during the pack step. Non-Julia applications can be bundled this way as well, as long as the user takes care of building and installing the application files in the setup callback.

Types

AppBundler.JuliaImg.JuliaImgBundleType
JuliaImgBundle(project; kwargs...)

Build specification for staging a Julia application as a self-contained image.

The Julia version is read from Manifest.toml in project (falling back to the running Julia version). Incremental compilation defaults to true when no sysimage packages are requested; building a sysimage forces incremental = false because a new sysimage invalidates all existing pkgimage caches.

Arguments

  • project::String: Path to the application directory containing Project.toml and Manifest.toml

Keyword Arguments

  • precompile::Bool = true: Precompile packages during staging. When false, precompilation is deferred to the first launch on the target system
  • incremental::Bool = isempty(sysimg_packages): Whether to reuse existing pkgimage caches. Automatically set to false when sysimg_packages is non-empty
  • sysimg_packages::Vector{String} = []: Packages to bake into the system image. Triggers a full sysimage rebuild, which invalidates all pkgimage caches
  • sysimg_args::Cmd =``: Extra command-line arguments forwarded to the sysimage compiler
  • remove_sources::Bool = false: Strip .jl source files from the staged package tree (only meaningful when all relevant packages are baked into the sysimage)
  • asset_spec::Dict{Symbol,Vector{String}} = Dict(): Selective asset inclusion rules. When empty, all artifacts are included and indexed via pkgorigin
  • asset_rpath::String = "assets": Destination subdirectory for assets when asset_spec is set
  • startup_file::String: Path to the startup.jl template. Resolved from meta/startup.jl inside project, falling back to $(pkgdir(AppBundler))/recipes/startup.jl

Examples

# Default: precompile everything, incremental caches
pkg = JuliaImgBundle("path/to/app")
 
# Skip precompilation — compile on first launch instead
pkg = JuliaImgBundle("path/to/app"; precompile = false)
 
# Bake heavy dependencies into a sysimage (forces non-incremental rebuild)
pkg = JuliaImgBundle("path/to/app"; sysimg_packages = ["Plots", "DifferentialEquations"])
source
AppBundler.JuliaC.JuliaCBundleType
JuliaCBundle(project; kwargs...)

Build specification for compiling a Julia application into a native executable via juliac.

Unlike JuliaImgBundle, which stages a full Julia runtime alongside precompiled package images, JuliaCBundle ahead-of-time compiles the application into a standalone native executable. The juliac tool must be installed and is looked up in bin/juliac under each entry of DEPOT_PATH, with ~/.julia/bin as a final fallback.

Arguments

  • project::String: Path to the application directory containing Project.toml

Keyword Arguments

  • juliac_cmd::Cmd = Cmd([juliac()]): Command used to invoke juliac. Defaults to the first juliac executable found on DEPOT_PATH
  • executable_name::String: Name of the produced executable. Defaults to the lowercase module name derived from Project.toml
  • trim::Bool = false: When true, passes --trim=safe to juliac, removing unreachable code from the output binary
  • args::Cmd =`: Additional arguments forwarded verbatim tojuliac`
  • asset_spec::Dict{Symbol,Vector{String}} = Dict(): Selective asset inclusion rules. When empty, no assets are copied into the bundle
  • asset_rpath::String = "assets": Destination subdirectory for assets inside destination

Examples

# Minimal: compile with defaults
pkg = JuliaCBundle("path/to/app")
 
# Enable dead-code trimming and a custom executable name
pkg = JuliaCBundle("path/to/app"; executable_name = "myapp", trim = true)
source
AppBundler.DMGType
DMG([overlay]; arch, compress, windowed, kwargs...)

Create a DMG configuration object for macOS application packaging.

When overlay is provided, configuration files are searched in overlay, then overlay/meta, then the built-in recipes directory. Application parameters (APP_NAME, APP_VERSION, etc.) are read from overlay/Project.toml, and packaging defaults (selfsign, compression, etc.) are read from overlay/LocalPreferences.toml. Without overlay, only the built-in recipes and the active project's LocalPreferences.toml are used.

Arguments

  • overlay: Path to a project directory containing Project.toml, optional LocalPreferences.toml, and optional meta/dmg/ overrides

Keyword Arguments

  • prefix = joinpath(dirname(@__DIR__), "recipes"): Base directory or array of directories to search for configuration files in sequential order
  • icon = get_path(prefix, ["dmg/icon.icns", "dmg/icon.png", "icon.icns"]): Path to application icon (.icns or .png)
  • info_config = get_path(prefix, "dmg/Info.plist"): Path to Info.plist template with app metadata
  • entitlements = get_path(prefix, "dmg/Entitlements.plist"): Path to entitlements file for code signing
  • dsstore = get_path(prefix, ["dmg/DS_Store.toml", "dmg/DS_Store"]): Path to DS_Store file or TOML template for Finder window appearance
  • selfsign: If true, generate a temporary self-signed certificate instead of using pfx_cert; defaults to selfsign preference
  • pfx_cert = get_path(prefix, "dmg/certificate.pfx"): Path to code signing certificate
  • shallow_signing: If true, sign only the top-level bundle rather than all nested binaries; defaults to dmg_shallow_signing preference
  • hardened_runtime: If true, enable hardened runtime during signing (required for notarization); defaults to dmg_hardened_runtime preference
  • sandboxed_runtime: If true, enable the App Sandbox entitlement; defaults to dmg_sandboxed_runtime preference
  • main_launcher: Path to the Julia entry-point script. When set, a native redirect launcher is installed at Contents/MacOS/<app_name> and the script itself at Contents/Libraries/main; resolved from prefix using the bundler predicate; omitted if not found
  • hfsplus = false: If true, use HFS+ filesystem when building the disk image otherwise uses ISO
  • windowed: If true, the application runs without a console window; defaults to windowed preference
  • compress: If true, pack the staging directory into a .dmg disk image; defaults to compress preference
  • compression: Compression algorithm for the disk image (:lzma, :bzip2, :zlib, or :lzfse); defaults to dmg_compression preference
  • arch = Sys.ARCH: Target CPU architecture
  • predicate: Bundler predicate used for hook selection; defaults to bundler preference
  • parameters: Dictionary of parameters for Mustache template rendering. When overlay is provided, pre-populated from Project.toml and preferences: APP_NAME, APP_DISPLAY_NAME, APP_VERSION, BUILD_NUMBER, APP_SUMMARY, APP_DESCRIPTION, BUNDLE_IDENTIFIER, PUBLISHER_DISPLAY_NAME, MODULE_NAME (Julia-based bundles only), WINDOWED, and SANDBOXED_RUNTIME

Examples

DMG()                                    # default recipes only
DMG(app_dir)                             # overlay with Project.toml parameters
DMG(app_dir; hardened_runtime = false)   # overlay with keyword overrides
DMG(; prefix = ["custom/", "recipes/"]) # explicit search path
source
AppBundler.MSIXType
MSIX([overlay]; arch, compress, windowed, kwargs...)

Create an MSIX configuration object for Windows application packaging.

When overlay is provided, configuration files are searched in overlay, then overlay/meta, then the built-in recipes directory. Application parameters (APP_NAME, APP_VERSION, etc.) are read from overlay/Project.toml, and packaging defaults (path_length_threshold, selfsign, etc.) are read from overlay/LocalPreferences.toml. Without overlay, only the built-in recipes and the active project's LocalPreferences.toml are used.

Arguments

  • overlay: Path to a project directory containing Project.toml, optional LocalPreferences.toml, and optional meta/msix/ overrides

Keyword Arguments

  • prefix = joinpath(dirname(@__DIR__), "recipes"): Base directory or array of directories to search for configuration files in sequential order
  • icon = get_path(prefix, ["msix/Assets", "msix/icon.png", "icon.png"]; dir = true): Path to application icon file or Assets directory
  • appxmanifest = get_path(prefix, "msix/AppxManifest.xml"): Path to MSIX application manifest template
  • resources_pri = get_path(prefix, "msix/resources.pri"): Path to package resource index file
  • msixinstallerdata = get_path(prefix, "msix/MSIXAppInstallerData.xml"): Path to installer configuration template
  • path_length_threshold: Maximum allowed path length; defaults to msix_path_length_threshold preference
  • skip_long_paths: If true, skip files exceeding path length threshold; if false, throw an error; defaults to msix_skip_long_paths preference
  • skip_symlinks: If true, skip file and directory symlinks; defaults to msix_skip_symlinks preference
  • skip_unicode_paths: If true, skip files with non-ASCII paths; defaults to msix_skip_unicode_paths preference
  • selfsign: If true, generate a temporary self-signed certificate instead of using pfx_cert; defaults to selfsign preference
  • publisher: Publisher string embedded in the manifest; defaults to msix_publisher preference
  • pfx_cert = get_path(prefix, "msix/certificate.pfx"): Path to code signing certificate
  • windowed: If true, the application runs without a console window; defaults to windowed preference
  • compress: If true, pack the staging directory into an .msix archive; defaults to compress preference
  • arch = Sys.ARCH: Target CPU architecture
  • predicate: Bundler predicate used for hook selection; defaults to bundler preference
  • parameters: Dictionary of parameters for Mustache template rendering. When overlay is provided, pre-populated from Project.toml and preferences: APP_NAME, APP_DISPLAY_NAME, APP_VERSION, BUILD_NUMBER, APP_SUMMARY, APP_DESCRIPTION, BUNDLE_IDENTIFIER, PUBLISHER_DISPLAY_NAME, MODULE_NAME (Julia-based bundles only), WINDOWED, and PUBLISHER

Examples

MSIX()                                    # default recipes only
MSIX(app_dir)                             # overlay with Project.toml parameters
MSIX(app_dir; skip_long_paths = true)     # overlay with keyword overrides
MSIX(; prefix = ["custom/", "recipes/"]) # explicit search path
source
AppBundler.SnapType
Snap([overlay]; arch, compress, windowed, kwargs...)

Create a Snap configuration object for Linux application packaging.

When overlay is provided, configuration files are searched in overlay, then overlay/meta, then the built-in recipes directory. Application parameters (APP_NAME, APP_VERSION, etc.) are read from overlay/Project.toml, and packaging defaults (windowed, compress, etc.) are read from overlay/LocalPreferences.toml. Without overlay, only the built-in recipes and the active project's LocalPreferences.toml are used.

Arguments

  • overlay: Path to a project directory containing Project.toml, optional LocalPreferences.toml, and optional meta/snap/ overrides

Keyword Arguments

  • prefix = joinpath(dirname(@__DIR__), "recipes"): Base directory or array of directories to search for configuration files in sequential order
  • icon = get_path(prefix, ["snap/icon.png", "icon.png"]): Path to application icon file
  • snap_config = get_path(prefix, "snap/snap.yaml"): Path to Snap package metadata template
  • desktop_launcher = get_path(prefix, "snap/main.desktop"): Path to desktop entry file template for GUI integration
  • configure_hook: Path to configuration hook script run on snap set; resolved from prefix using the bundler predicate; omitted if not found
  • main_launcher: Path to main launcher script installed into bin/; resolved from prefix using the bundler predicate; omitted if not found
  • windowed: If true, the application runs without a console window; defaults to windowed preference
  • compress: If true, pack the staging directory into a .snap archive; defaults to compress preference
  • arch = Sys.ARCH: Target CPU architecture
  • predicate: Bundler predicate used for hook selection; defaults to bundler preference
  • parameters: Dictionary of parameters for Mustache template rendering. When overlay is provided, pre-populated from Project.toml and preferences: APP_NAME, APP_DISPLAY_NAME, APP_VERSION, BUILD_NUMBER, APP_SUMMARY, APP_DESCRIPTION, BUNDLE_IDENTIFIER, PUBLISHER_DISPLAY_NAME, MODULE_NAME (Julia-based bundles only), and WINDOWED

Examples

Snap()                                    # default recipes only
Snap(app_dir)                             # overlay with Project.toml parameters
Snap(app_dir; windowed = false)           # overlay with keyword overrides
Snap(; prefix = ["custom/", "recipes/"]) # explicit search path
source

Functions

AppBundler.stageMethod
stage(product::JuliaImgBundle, destination::String;
      platform::AbstractPlatform = HostPlatform(),
      cpu_target = get_cpu_target(platform),
      runtime_mode = "MIN",
      app_name = "",
      bundle_identifier = "")

Stage a Julia application into destination, ready for packaging and distribution.

The staging process:

  1. Downloads and extracts the Julia runtime for platform (version from Manifest.toml)
  2. Copies all non-stdlib packages and artifacts into the stdlib tree
  3. Configures startup.jl, DEPOT_PATH, and LOAD_PATH via AppEnv
  4. Optionally compiles a system image from product.sysimg_packages
  5. Optionally precompiles pkgimages for all project dependencies

When product.precompile is true, platform must match the host OS and architecture (see cross-compilation constraints below).

Arguments

  • product::JuliaImgBundle: Staging configuration
  • destination::String: Directory in which the staged application is assembled

Keyword Arguments

  • platform::AbstractPlatform: Target platform; defaults to the current host
  • cpu_target: LLVM CPU target string; derived from platform by default
  • runtime_mode: AppEnv runtime mode string passed to AppEnv.save_config
  • app_name: Application name embedded in the AppEnv config
  • bundle_identifier: Bundle identifier embedded in the AppEnv config (e.g. reverse-DNS on macOS)

Cross-Compilation Constraints

Precompilation runs native code, so cross-OS and cross-architecture compilation is not supported when product.precompile = true:

  • Windows: host must be Windows
  • macOS: host must be macOS; x86_64 → aarch64 is not supported
  • Linux: host must be Linux with a matching architecture

Set precompile = false and sysimg_packages = [] in JuliaImgBundle to stage for a different platform without compilation.

Examples

pkg = JuliaImgBundle("src/MyApp")
 
# Stage for the current machine
stage(pkg, "build/staging")
 
# Stage for macOS arm64 (must run on Apple Silicon with precompile=false, or natively)
stage(pkg, "build/MyApp.app/Contents/Resources/julia";
      platform = Platform("aarch64", "macos"))
 
# Embed app identity in the AppEnv config
stage(pkg, "build/staging"; app_name = "MyApp", bundle_identifier = "com.example.myapp")
source
AppBundler.stageMethod
stage(spec::JuliaCBundle, destination::String;
      runtime_mode = "MIN",
      app_name = get_module_name(spec.project),
      bundle_identifier = "")

Compile a Julia application into a native executable and assemble it in destination.

The staging process:

  1. Saves an AppEnv config to destination/config with runtime identity and load-path settings
  2. Installs assets from spec.asset_spec into destination/<asset_rpath>
  3. Writes a pkgorigin index to destination/index for asset resolution at runtime
  4. Invokes juliac to AOT-compile the application and bundle the result into destination

Unlike JuliaImgBundle, no Julia runtime tarball is downloaded — juliac produces a self-contained native binary. The host toolchain must be compatible with the target.

Arguments

  • spec::JuliaCBundle: Compilation and asset configuration
  • destination::String: Directory in which the compiled application is assembled

Keyword Arguments

  • runtime_mode: AppEnv runtime mode string passed to AppEnv.save_config
  • app_name: Application name embedded in the AppEnv config; defaults to the module name
  • bundle_identifier: Bundle identifier embedded in the AppEnv config (e.g. reverse-DNS on macOS)

Examples

pkg = JuliaCBundle("src/MyApp")
 
# Stage into a directory
stage(pkg, "build/myapp";
      app_name = "MyApp", bundle_identifier = "com.example.myapp")
 
# Stage with a custom runtime mode
stage(pkg, "build/staging"; runtime_mode = "SANDBOX")
source
AppBundler.stageMethod
stage(config, destination::String; [dsstore=false])

Stage package metadata and directory structure into destination in preparation for bundling.

config is a format-specific configuration object — MSIX, DMG, or Snap — that carries the template files, parameters, and settings for the target platform. Mustache-rendered templates are written using the parameters stored in config.

stage is called automatically by bundle, but can be used directly when you need to inspect or modify the staging directory before compression and signing.

Staged layout by format

MSIX

  • Assets/ — application icons (generated from source or copied verbatim if already a directory)
  • AppxManifest.xml — rendered package manifest
  • resources.pri — package resource index
  • Msix.AppInstaller.Data/MSIXAppInstallerData.xml — rendered installer configuration

DMG

  • Contents/Resources/icon.icns — application icon
  • Contents/Info.plist — rendered application metadata
  • Contents/MacOS/<app-name> (optional) — native launcher when main_launcher is set

When dsstore = true, also writes into the parent of destination:

  • Applications — symlink to /Applications for drag-and-drop installation
  • .DS_Store — custom Finder window appearance

Snap

  • meta/icon.png — application icon
  • meta/snap.yaml — rendered Snap package metadata
  • meta/gui/<app-name>.desktop — rendered desktop launcher
  • meta/hooks/configure (optional) — configuration hook when configure_hook is set
  • bin/<app-name> (optional) — main launcher script when main_launcher is set

Examples

stage(MSIX(app_dir), "build/msix_staging")
stage(DMG(app_dir),  "build/MyApp.app"; dsstore = true)
stage(Snap(app_dir), "build/snap_staging")
source
AppBundler.bundleMethod
bundle(setup::Function, config, destination::String; force=false, [password=""])

Stage, populate, and optionally compress an application bundle for distribution.

config is a format-specific configuration object — MSIX (Windows), DMG (macOS), or Snap (Linux) — and destination is the path of the final artifact (e.g. "MyApp.msix", "MyApp.dmg", "MyApp.snap") or an uncompressed staging directory.

The function follows three steps:

  1. Stage — writes platform metadata and directory structure into a staging area via stage.
  2. Setup — calls setup(staging_dir), where you copy or compile the application files that should be included in the bundle.
  3. Pack — when config.compress is true (the default when destination carries the format extension), compresses the staging area into the final artifact and performs code signing.

Set force = true to overwrite an existing destination path.

Code signing

MSIX and DMG sign the bundle automatically during the pack step. Pass the certificate password via the password keyword argument (defaults to ""). When config.selfsign is true, a temporary self-signed certificate is generated instead of using the one in the configuration. DMG entitlements are rendered from the template stored in the configuration. Snap packages are not signed locally; they are verified by the Snap Store after upload.

Examples

bundle(MSIX(app_dir), "MyApp.msix") do staging_dir
    # copy or compile application files into staging_dir
end
 
bundle(DMG(app_dir), "MyApp.dmg") do staging_dir
    # copy or compile application files into staging_dir
end
 
bundle(Snap(app_dir), "MyApp.snap") do staging_dir
    # copy or compile application files into staging_dir
end
source
AppBundler.bundleMethod
bundle(product, packaging, destination; force=false, [password=""])

Bundle a Julia application product into a platform-specific package at destination by calling bundle(setup, config, destination) with product staged as the setup step.

Arguments

  • product: The application artifact to bundle. Either a JuliaImgBundle or a JuliaCBundle
  • packaging: The target package format. One of:
    • DMG — macOS disk image (.dmg). Must be built on macOS.
    • Snap — Linux Snap package. Must be built on Linux.
    • MSIX — Windows app package (.msix). Must be built on Windows.
  • destination: Output path for the produced package file.

Keyword Arguments

  • force=false: Overwrite an existing package at destination if true.
  • password="": Code-signing certificate password. Applicable to DMG and MSIX targets only.

A warning is emitted when the host OS does not match the target platform, as cross-platform packaging is not supported.

See also stage, bundle(setup, config, destination).

source