Shipping Sigil Applications
This guide explains how to package Sigil applications for distribution, covering the different commands and scenarios you'll encounter.
Overview
Sigil provides two commands for creating distributable applications:
sigil bundle- Package your app using the existing CLI runtime (fast, simple)sigil build- Build a custom runtime with full control over native dependencies
The right choice depends on your application's needs.
Quick Reference
| Scenario | Command | Result |
|---|---|---|
| Simple script | sigil bundle script.sgl | Uses CLI runtime |
| Multi-module app (no native deps) | sigil bundle myapp | Uses CLI runtime |
| App with TLS/crypto/SQLite | sigil build myapp | Custom runtime with native libs |
| Minimal binary size | sigil build myapp | Custom runtime, only needed deps |
Understanding the Two Commands
sigil bundle - Fast Packaging
The sigil bundle command creates a standalone executable by packaging your application into the existing Sigil CLI runtime. This is the fast path for distribution.
Bundling a single script:
sigil bundle script.sgl # Creates ./script executable
sigil bundle script.sgl -o dist/mytool # Custom output pathFor simple scripts, no package.sgl is needed. The script is compiled and embedded directly. Top-level code in the script runs immediately when the executable starts—no main procedure is required.
Bundling a multi-module application:
sigil bundle . # Bundle current directory
sigil bundle myapp/ # Bundle specific directory
sigil bundle myapp/ -o dist/myapp # Custom output pathFor multi-module applications, create a minimal package.sgl specifying the entry point. The entry module must define a main procedure that will be called when the executable starts:
(package
name: "myapp"
entry: '(myapp main))What it does:
- Takes the pre-built Sigil CLI binary as the base
- Compiles and embeds your modules (
.sgl→.sgbfiles) - Embeds any assets from your
assets/directory - Sets the entry point as the startup module
When to use:
- Your app only uses packages included in the CLI (stdlib, json, http, etc.)
- You want fast iteration during development
- You don't need to minimize binary size
Limitations:
- Cannot add native packages not already in the CLI
- Binary includes all CLI dependencies (larger size)
sigil build - Custom Runtime
The sigil build command compiles your application with full control, building a custom runtime that includes exactly the native dependencies your app needs.
sigil build myapp
sigil build myapp --config releaseWhat it does:
- Compiles all dependency packages
- Detects native packages (C code) in your dependency tree
- Generates a custom entrypoint that initializes native modules
- Links a custom runtime with only the needed native libraries
- Creates a standalone executable
When to use:
- Your app uses native packages (crypto, TLS, SQLite, custom C extensions)
- You want minimal binary size (only include what you use)
- You're building for a platform different from your development machine
Scenarios
Scenario 1: Simple Application
A basic application that uses only the standard library and pure-Scheme packages.
;; package.sgl
(package
name: "hello-world"
version: "1.0.0"
entry: '(hello main)
dependencies: (list
(from-workspace name: "sigil-stdlib")
(from-workspace name: "sigil-json")))Recommended: sigil bundle hello-world
The app has no native dependencies, so bundling with the CLI runtime is fastest. Pure-Scheme dependencies (like sigil-json, sigil-http) work fine with bundle since all .sgb files are replaced in the bundle anyway.
Scenario 2: Web Application with TLS
An application that makes HTTPS requests or serves HTTPS traffic.
;; package.sgl
(package
name: "web-client"
version: "1.0.0"
entry: '(web-client main)
dependencies: (list
(from-workspace name: "sigil-stdlib")
(from-workspace name: "sigil-http")
(from-workspace name: "sigil-tls")
(from-workspace name: "sigil-crypto")))Recommended: sigil build web-client --config release
The app needs TLS and crypto native libraries, so a custom runtime is built automatically.
Scenario 3: Database Application
An application that uses SQLite for local storage.
;; package.sgl
(package
name: "notes-app"
version: "1.0.0"
entry: '(notes main)
dependencies: (list
(from-workspace name: "sigil-stdlib")
(from-workspace name: "sigil-sqlite")))Recommended: sigil build notes-app --config release
SQLite is a native package, so a custom runtime includes the SQLite library.
Scenario 4: Application with Assets
An application with bundled data files, templates, or other assets.
;; package.sgl
(package
name: "my-app"
version: "1.0.0"
entry: '(my-app main)
dependencies: (list
(from-workspace name: "sigil-stdlib")))Place assets in the assets/ directory (by convention). They are automatically included in the bundle.
my-app/
├── package.sgl
├── src/
│ └── my-app/
│ └── main.sgl
└── assets/
├── templates/
│ └── report.html
└── data/
└── config.jsonRecommended: sigil bundle my-app
Accessing bundled assets:
(import (sigil resources))
;; Read a bundled file
(define template (resource-read "templates/report.html"))
;; Check if a resource exists
(resource-exists? "data/config.json")
;; Assets are accessed via @bundle/assets/ path internallyScenario 5: Minimal Distribution
When binary size matters (embedded systems, quick downloads).
;; package.sgl
(package
name: "tiny-tool"
version: "1.0.0"
entry: '(tiny-tool main)
dependencies: (list
(from-workspace name: "sigil-stdlib")))Recommended: sigil build tiny-tool --config release
Using sigil build creates a custom runtime that only includes the modules your app actually uses, rather than the full CLI with all its dependencies.
Build Configurations
Both commands support the --config flag to select a build configuration:
sigil build myapp --config dev # Local development (dynamic linking, fast builds)
sigil build myapp --config debug # Debug build (static linking, debug symbols)
sigil build myapp --config release # Release (static linking, optimized)Common Configurations
| Config | Static Linking | Optimization | Use Case |
|---|---|---|---|
dev | No | None | Local development, fast iteration |
debug | Yes (musl) | None | Debugging static builds |
release | Yes (musl) | O2 | Distribution |
Cross-Compilation
For building on one platform and running on another:
sigil build myapp --config linux-arm64 # Linux ARM64
sigil build myapp --config windows-amd64 # Windows x64
sigil build myapp --config macos-arm64 # macOS Apple SiliconCross-compilation requires the appropriate toolchain (zig or platform-specific cross-compiler).
Native Packages
Native packages contain C code that must be compiled and linked into the runtime. Sigil's native packages include:
| Package | Provides | Native Library |
|---|---|---|
sigil-crypto | SHA, HMAC, base64, random | libsigil-crypto.a |
sigil-tls | TLS/SSL connections | libsigil-tls.a |
sigil-sqlite | SQLite database | libsigil-sqlite.a |
When your app depends on a native package, sigil build automatically:
- Compiles the native code to a static library
- Generates an entrypoint that calls each package's init function
- Links everything into a custom runtime
Creating Native Packages
If you're writing a package with C code:
;; package.sgl
(package
name: "my-native-pkg"
version: "1.0.0"
dependencies: (list
(from-workspace name: "sigil-stdlib"))
libraries: (list
(library
name: 'my-native-pkg
c-sources: '("native/mycode.c")
c-include-dirs: '("native/include")
native-init: "my_pkg_init"))
tasks: (list
(task
name: 'build
steps: (list
(compile-c-sources
sources: '("native/mycode.c")
include-dirs: '("../sigil-lib/include"
"../sigil-lib/src"
"native/include"))
(create-static-library
name: "my-native-pkg")))))The native-init field specifies the C function called to register the module's primitives with the VM.
Troubleshooting
"Native packages detected but using CLI baseline"
This message appears when your app uses native packages that are already included in the CLI runtime. The build system reuses the CLI rather than building a custom runtime.
"Version mismatch detected"
When the CLI version differs from your project's dependency versions, a custom runtime is built to avoid compatibility issues.
"sigil-run executable not found"
The build system couldn't find a base runtime. Run make to build the bootstrap first.
Summary
- Use
sigil bundlefor fast packaging when your app fits within the CLI's capabilities - Use
sigil buildwhen you need native packages or minimal binary size - Native packages (crypto, TLS, SQLite) automatically trigger custom runtime builds
- Assets are bundled automatically from your
assets/directory - Cross-compilation is available via
--configflags