A .zsnap artifact packages a language's optional compiled grammar, checked
modules and optional lowered HIR. A host installs it before checking user source
so the runtime can reserve its type IDs and register its modules.
This reference covers artifact preparation and reuse. Language selection, type boundaries and symbol resolution are covered in Cross-language imports.
flowchart LR
Inputs[Optional grammar and checked modules] --> Builder[SnapshotBuilder]
Builder --> Artifact[Shared .zsnap artifact]
Artifact --> Validate[Validate compatibility]
Validate --> Install[Reserve type IDs and register modules]
Install --> Read[Read selected interfaces and bodies]
A build script supplies already checked programs:
let path = zyntax_embed::SnapshotBuilder::new("demo")
.module("prelude", checked_program)?
.build_in(&out_dir)?;build_in chooses the filename. include_snapshot! uses the same convention
under OUT_DIR, so hosts do not repeat filenames or format extensions:
let snapshot = std::sync::Arc::new(zyntax_embed::Snapshot::load(
zyntax_embed::include_snapshot!("demo"),
)?);
runtime.install_snapshot(snapshot)?;install_snapshot validates compatibility, registers the grammar when present,
reserves recorded type IDs and registers modules without decoding all their
bodies. Keep the Arc<Snapshot> available for reuse across runtimes.
For grammar-based frontends, .grammar(grammar.to_compiled_bytes()?) includes the
compiled parser. Native frontends can omit it. Host resolver callbacks remain
available for modules not packaged in the snapshot.
| Builder method | Saved data | Work remaining when consumed |
|---|---|---|
module / module_ref |
Checked typed AST | Native lowering and optimization |
module_with_source |
Checked AST plus original source | Same, with explicit source available for reparsing |
module_lowered |
Body-free declarations, signatures/interfaces and split HIR | Decode reached bodies and execute; JIT compilation remains runtime work |
module_lowered_ref borrows metadata that is already body-free, allowing its
owner to keep preparing HIR without copying typed function bodies.
module_ref borrows the checked program during encoding. module_lowered
consumes its program and strips executable AST bodies; matching HIR is required
for execution. Use shared lower_for_snapshot_releasing for library preparation,
or TieredRuntime::prepare_typed_program_snapshot to prepare a linked project
under the runtime's native policy. Preserve generic templates and use the same
release policy as the consuming runtime.
HIR uses the existing bytecode encoding. A snapshot contains neither a live heap nor native machine code. Programs still start in the interpreter and may promote through the JIT tiers.
module_interfacereads a compact interface when present; otherwise it falls back to the module.function_signaturereads a saved signature independently.- Split HIR keeps unused function bodies encoded. Embedded images borrow their
bytes; lazy modules share ownership through
Arc. into_modulesconsumes decoded programs instead of cloning them. A single owned lowered module reuses its image allocation for the encoded HIR.modulesrequests every module; avoid it when only selected imports are needed.
Checked programs retain their source-file metadata. module_with_source also
provides text through module_source for hosts choosing to reparse.
Readers check format versions and compiler fingerprints before decoding typed or HIR payloads. Lowered entries also validate target pointer size. Installation, interface/signature access and lazy body reads enforce compatibility; errors identify the affected module and incompatible identity.
A host can rebuild an incompatible snapshot or check its original source. Body-stripped declarations are not an executable source fallback. Raw AST entries retain their bodies and continue through normal native lowering.
Snapshot-generating build scripts call
zyntax_compiler::track_snapshot_build_inputs() so incremental regeneration watches
the shared compiler/type/codec inputs. Frontends must also track their own parser,
checking policy and native primitive dependencies.
SnapshotCache adds checked-source records to the ordinary snapshot format;
frontends do not need another cache container.
- Record every checked file with
SnapshotSource, including type-only files and resolved dependency edges. - Call
loadwith the frontend's current resolver. It validates source hashes, import resolution, options, frontend/compiler/target identity and payload checksum. Missing, stale, corrupt or incompatible entries are misses. - Use
storeto encode and atomically publish a complete entry. Alternatively,preparereturns an in-memory snapshot andpublishwrites it atomically. Publication failure leaves the prepared value usable by the current process.
A cache hit skips only the stages represented in the artifact: checked AST skips parsing/checking; compatible HIR also reuses native lowering and optimization. Artifact validation and runtime installation still run. Treat the cache directory as trusted local build storage.
SnapshotPreparation offers one shared background optimization slot per process.
It owns its HIR and metadata, revalidates source inputs, and publishes atomically.
optimize_inline can finish small graphs before scheduling a worker.
Dropping its handle cancels between compiler phases and publication writes without
joining; finish explicitly waits for prewarming. Callers keep an executable
fallback and include execution-root policy in their cache identity when saving
only reachable code.
See TypeScript caching for a frontend integration. Keep measurements and work journals in git-bug.