Sigil 0.17.0
0.17.0 is the browser release: you can now build and ship real web apps in Sigil! The whole browser stack is new and labeled experimental, but it is no longer a demo. It has been validated by building real applications on it: a browser game and a PWA chat client, both running on the new bridges with zero app-author JavaScript. This release also makes async networking more resilient, hardens the register VM and the reader, and cleans up a few standard library and build edges. Existing native projects keep building without changes.
Browser apps in Sigil (experimental)
A Sigil package can now declare a web build config and compile to a complete, servable web app. You check in your Sigil source, your CSS, and optionally a small HTML template; sigil build --config web generates the rest: the index.html shell, the runtime loader, the WebAssembly binary, and the bridge assets it needs. A new sigil serve command serves the output locally with correct MIME types and gzip compression, so the edit-build-reload loop needs no JavaScript tooling at all.
The browser bridges cover the APIs an app actually needs:
- DOM with SXML rendering, so you build and update your page's markup from Sigil data structures.
- WebSockets for real-time client networking.
- IndexedDB and localStorage for persistence.
- Canvas2D and WebGL for 2D and 3D graphics.
Bridge imports are dependency-gated: your app's .wasm only imports the bridges your package actually depends on, so a storage-only app carries no networking surface.
One honest caveat before you build on this: the browser and WASM APIs are still very experimental and driven by ongoing app development. They work today and are ready to explore, but their APIs may still shift before they are locked down.
How the browser modules are organized
The browser surface comes in two tiers. The raw platform layer lives under (sigil browser ...), with each module named after the Web platform API it wraps:
(sigil browser dom)and(sigil browser dom sxml), exportingdom-*(sigil browser websocket), exportingwebsocket-*(sigil browser canvas2d)and(sigil browser gl)(sigil browser local-storage),(sigil browser indexeddb), and(sigil browser async)
Most apps should not import these directly. The front doors are the portable libraries and the framework: (sigil websocket) for client networking and (sigil web client) for browser-side framework code. Reach for (sigil browser ...) only when no portable module covers the capability yet, like raw canvas access or storage.
If you experimented with the pre-release (sigil wasm ...) module paths from development builds, they still work in this release as deprecation aliases that re-export the old identifier names. They will be removed before 1.0, so use the (sigil browser ...) paths going forward.
Native WASM groundwork (experimental)
Sigil modules can now compile natively to browser WASM, the same native-codegen path used for native binaries. For synchronous apps this already works end to end: native browser builds start without the bytecode bundle, load fewer resources, and ship a smaller payload.
Async is the missing piece: await suspension is not implemented under native WASM yet, so any app that relies on the cooperative scheduler in the browser should use the bytecode path. Bytecode is the supported way to ship a browser app in 0.17.0; native WASM is groundwork worth watching, not the default.
Async DNS resolution
DNS lookups no longer freeze async programs. Previously, a stalled system resolver could block the cooperative scheduler inside getaddrinfo, freezing every fiber in the process. The runtime now offloads resolution to bounded worker jobs that wake the scheduler through fd readiness, so a slow or unreachable DNS server delays only the connection that asked for it.
This release ships the runtime side of the fix: the new resolver natives live in the Sigil runtime itself. The async socket API in the sigil-socket package uses them in its companion 0.17.0 release, so async socket users get the new behavior once both are in place.
A sturdier register VM
The register VM now handles very large module bodies without running out of registers, and it reports allocation overflow clearly instead of failing in a confusing way. Programs with big generated modules, like macro-heavy code or large data tables, are the main beneficiaries.
A more robust reader
The reader is now hardened against malformed, oversized, and pathological input. Where bad input could previously crash the process, hang it, or be silently misread, the reader now returns clean, catchable errors and reads edge-case literals exactly. If you parse data or code from sources you do not control, this release is a meaningful correctness upgrade. Regression tests shipped with the fixes.
Standard library and build tidy-ups
(scheme cxr)is now owned solely bysigil-r7rs. The duplicate copy was removed fromsigil-stdlibso the R7RS boundary is clean. Thecaar/cadrfamily of helpers stays available in(sigil core), so most code is unaffected.- Native build store keys now include the native tool inputs, so a change to the toolchain correctly invalidates cached build artifacts instead of serving a stale one.
- Workspace Sigil-version validation now checks each member against the workspace version rather than comparing member ranges against one another, and it only applies to workspaces that ship the language itself. This fixes false conflicts in monorepos that carry packages forward from an earlier language version, without affecting application workspaces. It also fixes a development-build regression where a freshly created
sigil initapp failedsigil deps installwith a spurious version conflict. - The reader accepts escaped-symbol syntax.
Known limitations
- The browser and WASM packages are experimental and outside the 1.0 stability plans. APIs may change between releases while the surface settles.
- Native WASM browser builds do not support async apps yet; bytecode is the supported browser path in this release.
- The async DNS natives ship in this release, but the
sigil-socketpackage release that uses them is still pending. Async socket code picks up the new behavior when the companionsigil-socket0.17.0 ships shortly after this release.