Sigil 0.14.0

release

The compiler, runtime, build system, and standard libraries have been split into their own repositories. codeberg:sigil/sigil is the user-facing CLI; codeberg:sigil/sigil-lang is the compiler and runtime; codeberg:sigil/sigil-build is the build system; and twenty-plus standalone library repos make up the rest of the ecosystem. To match this, packages declare a single sigil: field that the build system uses to specify which version range of Sigil they are compatible with. Most package manifests get smaller as a result.

Download 0.14.0Get started

This is a breaking change for the ecosystem. Existing packages that pull from the old monorepo URLs (e.g. (from-git url:"codeberg:sigil/sigil" package:"sigil-stdlib" ...)) need to migrate to the new extracted-repo URLs (codeberg:sigil/sigil-lang, codeberg:sigil/sigil-build, codeberg:sigil/sigil-X for individual libraries). The new URL conventions are listed in the extraction table below. Going forward, packages target the extracted repos directly and bump them on their own cadence; the monorepo no longer hosts library code.

The sigil: package field

Every Sigil package now declares which language version it targets:

(package
  name: "my-app"
  version: "0.1.0"
  sigil: "^0.14"
  ...)

The sigil: field is load-bearing build-system input. From it, the build system derives:

Existing packages that explicitly declare those deps continue to work; the auto-derive only injects when no explicit declaration is present. The win is in new packages and library refreshes: a typical pure-Scheme package.sgl no longer needs the (from-git url:"codeberg:sigil/sigil-lang" package:"sigil-stdlib" version:"^0.13.1") boilerplate every previous version required.

The field is now required for every package. Build commands fail loudly if a package manifest is missing sigil:; the error names the file and suggests the fix.

For multi-package workspaces, sigil: ranges across member packages must intersect. The build system pairwise-intersects member ranges and reports an honest error when they conflict, naming both members and their declared ranges.

The default-package: workspace field

Multi-package workspace repos can now declare a default package for cross-repo dependency references:

(workspace
  default-package: "sigil-build"
  packages: (list
    "packages/sigil-package"
    "packages/sigil-deps"
    "packages/sigil-build"))

When a downstream package writes (from-git url: "codeberg:sigil/sigil-build") without a package: selector, the resolver picks up the workspace's default-package: and uses it to disambiguate which sub-package to install. This makes single-package consumers of multi-package repos look like single-package consumers of single-package repos: no package: keyword needed for the common case.

The field is explicit-only; the build system does not infer a default. If a downstream package refers to a multi-package workspace via from-git without package: and the workspace doesn't declare default-package:, resolution errors loudly with the list of member packages so the consumer can pick.

The completed extraction

The package set extracted from codeberg:sigil/sigil over 0.12.x and 0.13.x is now closed. What stays in the monorepo (for now):

What lives in its own repo:

RepositoryContents
codeberg:sigil/sigil-langsigil-lib (C runtime), sigil-stdlib (standard library), compiler
codeberg:sigil/sigil-buildsigil-package, sigil-deps, sigil-build (build system + manifest + dep resolver)
codeberg:sigil/sigil-ansiterminal styling
codeberg:sigil/sigil-argscommand-line argument parsing
codeberg:sigil/sigil-cryptocryptography primitives (vendored mbedTLS)
codeberg:sigil/sigil-docsdocumentation generation
codeberg:sigil/sigil-ffiforeign function interface
codeberg:sigil/sigil-formatcode formatting
codeberg:sigil/sigil-gitgit integration
codeberg:sigil/sigil-hookslifecycle hooks
codeberg:sigil/sigil-httpHTTP client + server
codeberg:sigil/sigil-jsonJSON parsing + encoding
codeberg:sigil/sigil-logstructured logging
codeberg:sigil/sigil-lsplanguage server
codeberg:sigil/sigil-mcpMCP (Model Context Protocol) library
codeberg:sigil/sigil-nreplnetwork REPL protocol
codeberg:sigil/sigil-replREPL library
codeberg:sigil/sigil-socketsocket primitives
codeberg:sigil/sigil-sqliteSQLite (vendored amalgamation)
codeberg:sigil/sigil-storecontent-addressed storage
codeberg:sigil/sigil-testtest runner
codeberg:sigil/sigil-tlsTLS layer (consumes sigil-crypto)
codeberg:sigil/sigil-versionversion helpers
codeberg:sigil/sigil-webweb framework

Each library now releases on its own cadence. Mixed-version ecosystems are by design: sigil-http at v0.14.0 may pin sigil-stdlib at ^0.13, and that is fine. The extraction was about decoupling release cadences, not enforcing lockstep.

sigil cli upgrade and sigil cli use

sigil cli upgrade is faster, more reliable, and verifies binary integrity. Downloads now ship with mandatory sha256 checks; mismatched downloads are rejected and cleaned up. sigil cli use <version> lets you pin to a specific historical version on demand. The upgrade flow is now decoupled from any specific release-repo URL, so future hosting moves won't require a new sigil binary.

init templates refreshed

sigil init templates were updated for the post-pivot ecosystem. Each template's package.sgl now references the new extracted-repo URLs (codeberg:sigil/sigil-args, codeberg:sigil/sigil-http, codeberg:sigil/sigil-mcp, etc.) rather than the previous codeberg:sigil/sigil#vX.Y.Z + package: shape. The default *sigil-version* baked into newly-scaffolded projects bumped from v0.7.0 (badly stale) to ^0.14 and tracks current stable going forward.

Hygienic macros: syntax-case and quasisyntax

Sigil's hygienic macro implementation is now feature-complete enough to use as the primary macro system for any project. R6RS syntax-case with full hygiene, ellipsis patterns, and quasisyntax templates all work end-to-end. This matters because hygienic macros are the difference between "macros that occasionally surprise you with variable-capture bugs" and "macros that compose cleanly without a thought" — and well-written code in this style relies on the corner cases being correct.

Build system and dependency resolver

The dep resolver fails loudly where it used to fail silently. The 0.13.x resolver had several "report success and break the consumer at build time" failure modes; those are gone. New behavior is loud and named: when a fetch errors, when a lockfile entry diverges from the manifest, when a config name doesn't exist. The motivating goal: turn unreproducible build mysteries into immediate, actionable errors at the source.

Native codegen

Native builds are smaller, faster, and more visible. The CPS variable-declaration packing alone took the worst-case per-module zig-cc compile from "stuck at 24 minutes" to "completes cleanly," which makes native builds practical at the upper end of module size. Cumulative effect: native is now a comfortable default, not a "use at your own risk" path.

Bug fixes