RSTRust-First Site ToolkitA Rust-first static site generator with typed collections, explicit routes, and a format-agnostic asset pipeline.

Understand the design

Architecture

Understand the workspace split, rendering model, asset pipeline, and incremental build strategy.

Why the system is shaped this way

The framework is built around four constraints:

  1. the site author writes ordinary Rust

  2. authored content lives under content/

  3. reusable engine code lives in separate crates

  4. developer experience matters as much as raw feature count

Workspace layout

The current workspace uses these crates:

  • site-core: the public site-building API

  • site-assets: the internal asset pipeline

  • site-diagnostics: the shared diagnostic layer

  • avif-io: the internal AVIF boundary

  • site: the actual website program for this repository

This keeps site code readable while letting heavier media and diagnostic work evolve behind the public API.

Rendering model

Rendering is split into phases:

  1. load content and validate it

  2. expand the route set

  3. render each route into an artifact

  4. write outputs and record cache state

That phase split is why the API has more than one context type. The goal is clarity, not indirection.

Markdown and components

Markdown is not treated as a fixed HTML string. The renderer walks structured markdown and maps generated tags into component hooks such as a and img.

That gives the site program a direct place to:

  • replace link behavior

  • replace image behavior

  • integrate asset transforms

  • eventually attach richer components to authored content

Incremental build strategy

Across process runs, a route can be skipped when:

  • the program identity is unchanged

  • the handler identity is unchanged

  • the route dependencies hash to the same value

  • the expected output still exists

Asset outputs follow a similar idea, but their cache identity is based on source bytes plus a canonical transform description.

Asset model

Routes and markdown components request the output asset they want.

The engine then:

  1. resolves the authored reference

  2. fingerprints the source bytes

  3. fingerprints a canonical transform specification

  4. reuses or builds the transformed object in .site-cache/

  5. exposes a deterministic public URL under /assets/

This is why the site code can stay agnostic to whether an input image was SVG, PNG, JPEG, WebP, or AVIF.