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

Blog

Introducing the Asset Pipeline

The asset pipeline lets site code request the output it wants while keeping source formats, caching, and media transforms behind a smaller Rust API.

Ask for outputs, not source-specific operations

One of the design goals of this project is that route code should stay close to the intent of the site.

For assets, that means the site should ask for the output it wants:

  • an OpenGraph JPEG

  • a responsive AVIF image

  • a preserved SVG

It should not have to branch on whether the authored source is SVG, PNG, JPEG, WebP, or AVIF.

That is the job of the asset pipeline.

The public API surface

The main site-facing entry points are:

  • RenderContext::asset_url(...)

  • RenderContext::image_url(...)

  • RenderContext::responsive_image(...)

  • ImageOutput

  • ResponsiveImageOutput

Markdown components can use the same ideas through:

  • ComponentProps::asset_url(...)

  • ComponentProps::image_url(...)

  • ComponentProps::responsive_image(...)

That is the feature boundary the site author normally needs to learn.

The site-facing API stays format-agnostic

From route code, the public surface is intentionally small:

  • ctx.asset_url(...)

  • ctx.image_url(...)

  • ctx.responsive_image(...)

From markdown components, the same ideas are available through ComponentProps.

The route asks for a destination shape, not an implementation recipe:

let open_graph = ctx.image_url(
    entry,
    reference,
    &ImageOutput::raster(ImageFormat::Jpeg, 1200, 630)
        .with_fit(ImageFit::Cover)
        .with_background(BackgroundColor::rgb(248, 244, 234))
        .rasterize_vector_inputs(),
)?;

That code does not need to know whether the authored image started life as an SVG, an HDR AVIF, or something else.

Vector inputs stay vector by default

SVG is a good example of the API shape.

In most sites, an authored SVG should remain SVG. The pipeline therefore preserves vector inputs by default even if the requested output shape is written as an "image request".

Rasterization is opt-in:

  • ordinary page imagery can stay vector

  • raster-only destinations such as OpenGraph JPEGs can explicitly opt in

That default keeps the common path fast and unsurprising.

Caching is based on source bytes plus a canonical transform

The pipeline fingerprints:

  • the authored source bytes

  • a canonical transform description

  • any processor cache keys that participate in the final output

This matters because the pipeline should not redo work just because the same request was made from another page, another build, or a differently ordered configuration value.

The cache key tracks behavior, not just filenames.

HDR stays inside the engine

The site-facing API does not expose an SDR/HDR toggle.

If the source asset carries HDR semantics and the requested output format can preserve them, the pipeline keeps them internally. If the destination cannot preserve the authored semantics safely, the pipeline rejects the transform instead of silently guessing.

That keeps site code simpler while still taking color behavior seriously.

Where to go next