Sigil 0.8.0
Dynamic FFI and portable foundations. Sigil gains the ability to call any C library at runtime without writing glue code, a content-addressable build cache for faster incremental builds, and seven new packages spanning graphics, game development, calendar sync, and messaging. Cross-compilation now passes across all eight platform targets, and a new app management system makes it easy to install and run Sigil applications from git repos. With this release, Sigil reaches a stability point that enables us to begin decoupling libraries from the monorepo for independent releases and faster iteration.
Dynamic FFI
The headline feature. sigil-ffi lets you call C library functions directly from Scheme without writing any C glue code. Load shared libraries with ffi-open, look up symbols with ffi-ref, define call signatures, and invoke — all at runtime.
(import (sigil ffi))
(define lib (ffi-open "libm.so.6"))
(define c-sqrt (ffi-ref lib "sqrt" '(double) 'double))
(c-sqrt 144.0) ; => 12.0- Callbacks:
c-callbackcreates function pointers that call back into Scheme, enabling integration with event-driven C APIs like GUI toolkits - Pointer finalizers:
set-pointer-finalizer!attaches GC-triggered cleanup to foreign pointers (pass#fto clear) - dyncall backend: Replaced pure-C trampolines with dyncall for portable calling convention support, including mixed int/double argument signatures used by Cairo and similar libraries
Content-Addressable Build Store
A new sigil-store package provides content-addressable storage for build artifacts. C compilation results and static libraries are cached by content hash, so unchanged native code is never recompiled. Build outputs are properly rooted for GC, and the store integrates transparently with the existing build system.
App Management
New sigil app commands for installing, updating, and removing Sigil applications from git repositories:
sigil app install— clone a repo, resolve dependencies, bundle the app, and register any MCP serverssigil app list— show installed applicationssigil app update— pull latest changes and rebuildsigil app remove— clean up installed app and deregister MCP serverssigil app rollback— revert to the previous version
Supports --scope for MCP server registration, --env and secret-env for configuration, and graceful handling of missing environment variables.
New Packages
| Package | Description |
|---|---|
sigil-ffi | Dynamic FFI for calling C libraries at runtime via dyncall |
sigil-cairo | Cairo 2D graphics bindings — paths, transforms, surfaces, PNG loading, compositing operators, glyph rendering |
sigil-freetype | FreeType font loading and glyph metrics via FFI |
sigil-harfbuzz | HarfBuzz text shaping via FFI |
sigil-raylib | Raylib game development bindings — 2D shapes, text, input, collision, audio |
sigil-caldav | CalDAV calendar client with iCalendar parsing, event CRUD, recurrence expansion, timezone handling |
sigil-telegram | Telegram Bot API client with bot framework, MarkdownV2 formatting, inline keyboards, file uploads |
MCP Server Improvements
- Channel servers: New
(sigil mcp channel)module with helpers for building MCP channel-based servers (stdin/stdout transport) - Server-initiated notifications: MCP servers can now push notifications to clients, declare custom capabilities, and provide instructions
- Structured logging: MCP message handling uses
sigil-logwithlog-configure-from-args!for CLI integration - Better error reporting: Stack traces included in MCP tool error responses
HTTP Improvements
/jsonroute helpers now return JSON bodies on all HTTP status codes, not just 2xxurl-encode-valueandbuild-query-stringfor proper URL query parameter encoding- Fixed UTF-8 split across HTTP read chunk boundaries
- Fixed chunked transfer decoding for non-ASCII UTF-8 content
- Fixed
Content-Lengthusing character count instead of byte length - Fixed partial socket writes truncating large HTTP responses
- Unix domain socket server support via
unix-listen
CalDAV and iCalendar
Beyond the new sigil-caldav package, significant improvements to calendar handling:
- Timezone-aware datetime parsing with correct DST offset calculation via
mktime - Attendee parameter support for event creation
- Calendar name and timezone fields on
ical-event - RRULE recurrence expansion with
RECURRENCE-IDexception suppression - Date range filtering for non-recurring events in recurrence expansion
Formatter Performance
The code formatter was optimized from 30 seconds to under 2 seconds on large files (2800+ lines):
- Replaced struct-based tokens with raw vectors
- Inlined tokenizer hot loops with delimiter lookup table
- Zero-allocation form type matching
- Fixed tokenizer mishandling of delimiter character literals
Build System
- Content-addressable store for cached C compilation and static libraries
- Fixed build cache ignoring dependency changes
- Fixed false source file matches in module dependency resolution
- Fixed test runner dependency resolution for external packages
- Fixed build store hard-link self-copy corruption
- Hardened test runner against load errors
- Default release/prerelease configs switched to glibc dynamic linking (supporting FFI and dlopen)
- Static build configs available as
release-staticandprerelease-static
JMAP Improvements
jmap-email-countfor lightweight email counting without fetching messagesjmap-download-blobfor downloading JMAP blobs to files- Batch email move support
- Fixed send compatibility issues
Performance and Code Quality
- Fixed quadratic
string-join— now uses linear accumulation - Improved
list-unzipto use simultaneous traversal - Deduplicated
inspect-vectorandinspect-arraywith shared helper - Dict-based lookups in diagnostic module and watch module for faster type-guard and mtime resolution
Bug Fixes
- Fixed crash when
formatdisplays bignum values - Fixed segfault from unbounded macro export recursion
- Fixed preemptive yield escaping through
sigil_applyboundaries - Fixed
string->listto properly decode UTF-8 characters - Fixed
string-joinoverflow with large lists - Fixed double-encoded UTF-8 in build output and diagnostics
- Fixed YAML encoder to handle Sigil arrays
- Raised module binding limit from 2048 to 4096
- Fixed async stdin handling for MCP servers (pipe detection, fd-waiter integration)
- Fixed
char-ready?for pipes with async-aware stdin polling - Added Scheme module definition for
sigil-tlspackage - Fixed Windows cross-compilation:
fcntl/FD_CLOEXECguards replaced withSetHandleInformation - Fixed OpenBSD cross-compilation:
setvbufworkaround for opaqueFILEstruct in Zig headers - Fixed OpenBSD executable path resolution, poll fd limit, and partial write handling
- Set
FD_CLOEXECon TCP sockets to prevent child process inheritance