Expand description
§Hauchiwa
A flexible, incremental, graph-based static site generator library for Rust. It provides the building blocks to create your own custom static site generator tailored exactly to your needs.
Unlike traditional SSGs that force a specific directory structure or build pipeline, Hauchiwa gives you a task graph. You define the inputs (files, data), the transformations (markdown parsing, image optimization, SCSS compilation), and the dependencies between them. Hauchiwa handles the parallel execution, caching, and incremental rebuilds.
If you are tired of:
- Rigid frameworks that force their file structure on you (Jekyll, Hugo).
- Complex config files that are hard to debug.
- Bloated JavaScript bundles for simple static content.
Then Hauchiwa is for you.
§Key Features
- Graph-based: Define your build as a graph where tasks are wired together using strictly typed handles rather than rigid file paths. This structure automatically resolves complex dependencies, ensuring shared ancestor tasks execute exactly once before efficiently distributing their results.
- Incremental: The engine identifies the specific task responsible for a changed file and marks only its dependent subgraph as “dirty”. By re-executing only this precise chain of tasks, the system avoids wasteful full rebuilds and delivers near-instant updates.
- Parallel: A threaded execution engine schedules tasks to run on a thread pool the moment their dependencies are resolved. This saturates your CPU cores automatically, processing heavy assets and content concurrently without manual async orchestration.
- Type-safe: Dependencies are passed as generic tokens, allowing the Rust compiler to enforce that a producer’s output type perfectly matches a consumer’s input. Advanced static verification prevents broken builds by catching data flow errors at compile time rather than runtime.
- Asset pipeline: Built-in support for:
- Images: Automatically generates multi-format
sources (WebP, AVIF) with content-addressed hashing for immutable caching
via the
imagecrate. - CSS/Sass: Integrates
grassto compile and minify stylesheets, outputting hashed CSS bundles that are ready for aggressive browser caching. - JavaScript: Bundling and minification via
esbuild. - Svelte: Orchestrates Deno to compile components into separate SSR and hydration scripts, automatically propagating import maps for seamless client-side interactivity.
- Search: Static search indexing via
pagefind. - Sitemap: Sitemap generation via
sitemap-rs.
- Images: Automatically generates multi-format
sources (WebP, AVIF) with content-addressed hashing for immutable caching
via the
§Core Concepts
- Blueprint: The blueprint of your site. You use this to register tasks and loaders.
- Task: A single unit of work. Tasks can depend on other
tasks.
- Coarse-grained: Tasks that produce a single output.
- Fine-grained: Tasks that produce multiple outputs.
- Handle: A reference to the future result of a task. You pass these to other tasks to define dependencies.
- Loader: A kind of a task that reads data from the filesystem (e.g., markdown files, images).
- Website: The engine that converts the graph defined in
Blueprintinto a proper static website.
§Quick Start
Add hauchiwa to your Cargo.toml:
[dependencies]
# Check crates.io for the latest version
hauchiwa = "*"
# Serde is needed to parse frontmatter
serde = { version = "1", features = ["derive"] }Create your generator in src/main.rs:
use hauchiwa::{Blueprint, Website, Output};
use serde::Deserialize;
// 1. Define your content structure (Frontmatter)
#[derive(Deserialize, Clone)]
struct Post {
title: String,
}
fn main() -> anyhow::Result<()> {
// 2. Create the configuration
// We explicitly specify the global data type as `()`
// since we don't have any global state yet.
let mut config = Blueprint::<()>::new();
// 3. Add a loader to glob markdown files
// `posts` is `Many<Document<Post>>`
let posts = config.load_documents::<Post>()
.source("content/**/*.md")
.register()?;
// 4. Define a task to render pages
// We declare that this task depends on `posts`.
config.task()
.depends_on(posts)
.run(|_, posts| {
let mut pages = Vec::new();
// Iterate over loaded posts
for post in posts.values() {
let html_content = format!("<h1>{}</h1>", post.matter.title);
// Create a page structure
// Output::html creates pretty URLs (e.g., /foo/index.html)
pages.push(Output::html(&post.meta.path, html_content));
}
Ok(pages)
});
// 5. Build the website
let mut website = config.finish();
website.build(())?;
Ok(())
}§Feature flags
By default, Hauchiwa is built with the following features, but you can opt out
of them by disabling them in your Cargo.toml file, if you don’t need them.
grass: Enables SCSS/Sass compilation.image: Enables image optimization (WebP, resizing).tokio: Enables the Tokio runtime for async tasks.live: Enables live-reload during development.server: Enables the built-in development server.pagefind: Enables static search indexing.sitemap: Enablessitemap.xmlgeneration.
§Documentation
Introduction is available in the docs/ directory (run make watch), or you
can visit the online version. The best place to
learn the API is the full documentation. It covers
the available features in depth.
§Examples
Some examples are available in the examples/ directory.
In addition, there are also some real-world examples:
§License
GPL-2.0 or later.
Re-exports§
Modules§
- error
- loader
- Loaders are tasks that ingest data from the filesystem or external sources.
- output
- Utilities for working with output data and paths.
- prelude
- tracing
Structs§
- Blueprint
- The blueprint for your static site.
- Diagnostics
- Build diagnostics and performance metrics.
- Environment
- Global configuration and state available to all tasks.
- File
Metadata - Metadata about a file in the project structure.
- Import
Map - This matches the browser’s Import Map specification. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
- Many
- A “fine” type-safe reference to a task in the build graph.
- One
- A “coarse” type-safe reference to a task in the build graph.
- Store
- A helper for managing side effects and imports within a task.
- Task
Context - The context passed to every task execution.
- Tracker
- A collection of assets tracked with fine-grained granularity.
- Website
- Represents the configured site and provides methods for building and serving it with a development server.
Enums§
- Mode
- The mode in which the site generator is running.