Contents
- Install -- Cargo, Homebrew, apt, AUR, one-liner
- Quick Start -- scaffold a site in 30 seconds
- Overview -- what SSG does
- Architecture -- build pipeline diagram
- Benchmarks -- performance and test suite metrics
- Features -- v0.0.45 capability matrix
- The CLI -- flags and usage
- Library Usage -- plugins, schemas, AI pipeline
- Examples -- 8 branded examples
- Development -- make targets, CI workflows
- Security -- safety guarantees and compliance
- License
Install
[]
= "0.0.45"
Prebuilt binaries
# macOS / Linux -- one command
|
# Homebrew
# Cargo
# Debian / Ubuntu
# Arch Linux (AUR)
# Container
Build from source
Requires Rust 1.88.0+. Tested on Linux, macOS, and Windows.
Quick Start
# 1 -- Install
# 2 -- Scaffold a new site
# 3 -- Build
# 4 -- Development server with live reload
# 5 -- AI-powered readability fix (requires Ollama)
Overview
SSG generates static websites from Markdown content, YAML frontmatter, and MiniJinja templates. It compiles everything into production-ready HTML with built-in SEO metadata, WCAG 2.2 AA accessibility compliance (including the new 2.5.8, 2.4.13, 3.2.6 criteria where automatable), multilingual readability scoring, and feed generation. The 33-plugin pipeline handles the rest.
- 33-plugin pipeline -- SEO, a11y, i18n, search, images, AI, CSP, JSON-LD, RSS, sitemaps
- Agentic AI pipeline -- audit, diagnose, fix, and verify content readability via local LLM
- Multilingual readability -- Flesch-Kincaid (EN), Kandel-Moles (FR), Wiener Sachtextformel (DE), Gulpease (IT), LIX (SV), Fernandez Huerta (ES)
- Incremental builds -- content fingerprinting via FNV-1a hashing and dependency graph
- Streaming compilation -- configurable memory budgets for 100K+ page sites
- WCAG 2.2 AA -- accessibility checked on every build (non-blocking by default; reports written to
accessibility-report.json+wcag-compliance.json) and gated in CI by axe-core. Build-failure on a11y violations is opt-in via theSTRICT_A11Yenv var (implemented in v0.0.40) - Zero unsafe code --
#![forbid(unsafe_code)]across the entire codebase
Architecture
graph TD
A[Content: Markdown + YAML] --> B{SSG CLI}
B --> V[Content Schema Validation]
V --> C[Incremental Cache + `DepGraph`]
C --> D[Compile: staticdatagen]
D --> E[Post-Processing Fixes]
E --> F[Fused Transform Pipeline: 33 plugins]
F --> G[Output: HTML + RSS + Atom + Sitemap + JSON-LD]
B --> H[File Watcher + CSS HMR]
H -->|changed files| C
B -->|--serve| S[Dev Server + Live Reload + Error Overlay]
B -->|--ai-fix| AI[Agentic LLM Pipeline]
AI -->|audit + fix| A
Benchmarks
| Metric | Value |
|---|---|
| Source | 71,000+ lines across 6 workspace crates (ssg, ssg-core, ssg-search, ssg-rpc, ssg-rpc-macro, ssg-wasm) |
| Test suite | 2,418 unit tests + 36 integration test suites |
| Coverage | 95% region, 95% line, 95% function (CI-gated) |
| Plugin pipeline | 38 plugins, Rayon-parallelised |
| Audit gates | 14 (WCAG 2.2 AAA, JSON-LD, hreflang, CSP+SRI, PQC TLS, HTML5, broken links, OG, markdown lint, perf budget, AI discovery, RSS/Atom, image opt, search index integrity) |
| Examples | 8 branded sites + 2 edge-runtime adapters (Cloudflare Workers, Vercel Edge) |
| Edge runtimes | Cloudflare Workers + Vercel Edge with ISR (ssg-wasm) |
| Search | Browser-native int8 vector embeddings via ssg-search (WASM, ≤2 MB gzipped budget) |
| MSRV | Rust 1.88.0 |
Build performance
| Pages | Time | Memory |
|---|---|---|
| 100 | < 5s (CI-gated) | < 100 MB |
| 1,000 | < 10s | < 200 MB |
| 10,000 | Streaming batches | 512 MB budget |
| 100,000+ | Streaming compilation | Configurable via --max-memory |
Reproduce: cargo bench --bench bench -- scalability.
Features
| Performance | Parallel file operations with Rayon, fused single-pass HTML transforms, content-addressed caching (FNV-1a), dependency graph for incremental rebuilds, streaming compilation for 100K+ pages, --jobs N thread control, --max-memory MB budget |
| AI Pipeline | Agentic LLM pipeline (--ai-fix): audit content readability, diagnose failing files, generate fixes via local LLM (Ollama), verify improvement, produce JSON report. Dry-run mode (--ai-fix-dry-run). Auto-generate alt text, meta descriptions, and JSON-LD via LLM |
| Readability | Multilingual scoring: Flesch-Kincaid (EN), Kandel-Moles (FR), Wiener Sachtextformel (DE), Gulpease (IT), LIX (SV/NO/DA), Fernandez Huerta (ES). BCP 47 language detection from frontmatter. CI readability gate |
| Content | Markdown with GFM extensions (tables, strikethrough, task lists), YAML/TOML/JSON frontmatter, typed content schemas with compile-time validation, shortcodes (youtube, gist, figure, admonition), compile-time word count + estimated reading time injected into .meta.json sidecars |
| SEO | Meta description, Open Graph (title, description, type, url, image, locale), auto-generated OG social cards (SVG), Twitter Cards, canonical URLs, robots.txt, sitemaps with per-page lastmod, first-class topic-cluster taxonomy (hub + pillar indexes), related-post discovery via Jaccard tag/category overlap |
| Structured Data | JSON-LD Article/WebPage with datePublished, dateModified, author, image, inLanguage, BreadcrumbList |
| Syndication | RSS 2.0 with enclosures and categories, Atom 1.0, Google News sitemap |
| Accessibility | WCAG 2.2 AA validation on every build (1.1.1, 1.3.1, 2.3.1, 2.4.4, 2.4.13, 2.5.8, 3.1.1, 3.2.6), axe-core Playwright CI, decorative image detection, heading hierarchy, ARIA landmarks; emits wcag-compliance.json matrix (WCAG 2.2 + EAA guide) |
| i18n | Hreflang injection, x-default support, per-locale sitemaps, language switcher HTML |
| Images | Responsive <picture> with WebP sources, srcset at 320/640/1024/1440, lazy loading, CLS prevention, optional cdn_prefix for serving local image assets from a CDN host |
| Templates | MiniJinja engine with inheritance, loops, conditionals, custom filters |
| Search | Client-side full-text search with modal UI, 28 locale translations, Ctrl+K / Cmd+K |
| Security | CSP build-time extraction (zero unsafe-inline), SRI hash generation, asset fingerprinting, path traversal prevention, structured SsgError type-safe error hierarchy |
| Minification | Native HTML / JS / CSS minification (opt-in minify feature) via minify-html 0.15 (HTML, <pre> preserved), oxc_minifier 0.95 (JS, mangle + DCE), and lightningcss 1.0.0-alpha.71 (CSS). Recursive walk processes every .html, .css, and .js file under site_dir regardless of depth. |
| Supply Chain | Automated CycloneDX 1.5 SBOM (sbom.cdx.json) generated on every build via SbomPlugin, listing compiler version, dependency tree, and license metadata |
| DX | CSS hot reload, browser error overlay via WebSocket, file watching with change classification |
| WebAssembly | ssg-core + ssg-wasm + ssg-search compile to wasm32-unknown-unknown with wasm-bindgen; ssg-wasm ships ISR + RPC entry points for Edge runtimes (CI-enforced ≤ 2 MB gzipped) |
| Vector search | ssg-search — browser-native int8-quantised hashed-n-gram (or opt-in model2vec-rs) embeddings, Float32Array boundary, no division / sqrt at runtime, p99 < 100 ms on 1000-doc corpus (CI-gated) |
| Edge runtimes | Cloudflare Workers + Vercel Edge adapters with KV / Edge Config content provider, SHA-256-keyed ISR manifest, invalidation webhook, optional View Transitions client (transitions = true) |
| Edge RPC | #[ssg_rpc] proc-macro, JSON-over-POST dispatch, schemars 1.2 + custom JSON-Schema → TypeScript emitter, golden .d.ts test |
| Edge headers | Per-host emitters for Cloudflare _headers, Netlify _headers, Vercel vercel.json with PQC TLS guidance (X25519+ML-KEM-768 hybrid notes) |
| Audit CLI | ssg audit runs 14 gates (WCAG 2.2 AAA, JSON-LD, hreflang, CSP+SRI, PQC TLS, HTML5, broken links, OG, markdown lint, perf budget, AI discovery, RSS/Atom, image opt, search index integrity); JSON / JUnit / SARIF v2.1.0 / text outputs (v0.0.45 #562, GitHub Code Scanning ingestible) |
| Architecture Decision Records | Six baseline ADRs under docs/adrs/ in Nygard format documenting the tokio-free architecture, Rayon orchestration, lol_html selection, sync tungstenite HMR, ureq LLM transport, and CycloneDX-over-SPDX SBOM choice. CI-enforced adr: ADR-NNNN citation graph (v0.0.45 #557) |
| Supply-chain attestation | cargo-vet (v0.0.45 #561) layers per-crate audit attestation over cargo deny's license + CVE checks. Imports Mozilla Firefox, Bytecode Alliance, and Google trust sets; exemption-reduction policy in supply-chain/README.md |
| Concurrency proofs | Miri job (.github/workflows/miri.yml, v0.0.45 #560) runs cargo miri test --lib on a nightly schedule + run-miri-labelled PRs. Loom + Kani follow in v0.0.46 (#564 / #565) |
| Feature-matrix CI | cargo hack check --feature-powerset --depth 2 (v0.0.45 #584) exercises every reachable subset of {ai, benchmark, cli, image-optimization, minify, otel, templates, test-fault-injection} on every PR — catches cfg-gating gaps before they merge |
| Agentic discovery | Opt-in /agents.txt (robots-style AI agent allow/deny), /.well-known/ai-plugin.json (OpenAI plugin manifest), /.well-known/mcp.json (Model Context Protocol registry with auto-populated resources) |
| ISO 20022 JSON-LD | Schema.org descriptors for regulated financial sites: BankAccount, FinancialProduct, MonetaryAmount, PaymentInstrument, RegulatedFinancialInstitution. Built-in IBAN + BIC validators |
| View Transitions | Opt-in (transitions = true) View Transitions API client + lazy hydration; persistent <header> / <footer> get view-transition-name so they don't animate across boundaries; falls back to plain reload in non-supporting browsers |
| Islands | Web Components with lazy hydration (visible, idle, interaction) |
Why SSG?
| Capability | SSG | Hugo | Zola | Astro |
|---|---|---|---|---|
| Agentic AI pipeline | Yes | No | No | No |
| Multilingual readability | Yes | No | No | No |
| Auto-generated OG images | Yes | No | No | Plugin |
| Built-in WCAG validation | Yes | No | No | No |
| CSP/SRI auto-extraction | Yes | No | No | Plugin |
| axe-core CI gate | Yes | No | No | No |
| WebAssembly target | Yes | No | No | N/A |
| 95% CI coverage floors | Yes | No | No | No |
| Zero unsafe code | Yes | Yes | Yes | N/A |
The CLI
ssg ships with both a unified subcommand surface (introduced in v0.0.43) and the legacy bare-flag pipeline (preserved with a deprecation warning, removal in 1.0).
Subcommands (recommended)
Usage: ssg <COMMAND> [OPTIONS]
Commands:
dev Start the development server with HMR + WebSocket reload
build One-shot site build (supports --incremental, --isr, --no-llm-cache)
check Validate content schemas without writing
audit Run 14 audit gates against an already-built site (--out json|junit|text)
deploy Generate deployment config for netlify | vercel | cloudflare | github
help Print this message or the help of the given subcommand(s)
Build flags (v0.0.45)
--incremental Skip recompile when DepGraph diff is empty (issue #524)
--isr Emit an SHA-256-keyed ISR manifest for Edge adapters (issue #549)
--no-llm-cache Bypass the deterministic LLM inference cache (issue #528)
Legacy flags (still supported)
-f, --config <FILE> Configuration file path
-n, --new <NAME> Create new project
-c, --content <DIR> Content directory
-o, --output <DIR> Output directory
-t, --template <DIR> Template directory
-s, --serve <DIR> Start development server (HMR + livereload)
-w, --watch Watch for changes and rebuild
-j, --jobs <N> Rayon thread count (default: num_cpus)
--max-memory <MB> Peak memory budget for streaming (default: 512)
--ai-fix Run agentic AI pipeline to fix content readability
--ai-fix-dry-run Preview AI fixes without writing changes
--validate Validate content schemas and exit
--drafts Include draft pages in the build
--deploy <TARGET> Generate deployment config (netlify, vercel, cloudflare, github)
-q, --quiet Suppress non-error output
--verbose Show detailed build information
-h, --help Print help
-V, --version Print version
Library Usage
use ;
use SsgError;
use Path;
;
Create content/content.schema.toml:
[[]]
= "post"
[[]]
= "title"
= "string"
= true
[[]]
= "date"
= "date"
= true
[[]]
= "draft"
= "bool"
= "false"
Pages with schema = "post" in their frontmatter are validated at compile time. Run ssg --validate for schema-only checks.
use ;
use Path;
let report = audit_all.unwrap;
println!;
// Multilingual: French content uses Kandel-Moles automatically
// when frontmatter contains `language: fr`
use generate_og_svg;
let svg = generate_og_svg;
write.unwrap;
// 1200x630 SVG social card ready for og:image
use ;
use VectorEngine;
// Build side: turn a doc corpus into the 4-file artifact blob.
let docs = vec!;
let arts = from_docs;
write.unwrap;
write.unwrap;
write.unwrap;
// Runtime (native or WASM): load and query.
let engine = new.unwrap;
let top = engine.search;
println!;
use ssg_rpc;
use JsonSchema;
use ;
// The build emits `site/rpc.d.ts` automatically; clients call:
// const r = await ssgRpc("echo", { msg: "hi" });
# 14 gates run: WCAG 2.2 AAA, JSON-LD, hreflang, CSP+SRI, PQC TLS,
# HTML5, broken links, OG, markdown lint, perf budget, AI discovery,
# RSS/Atom, image opt, search index integrity.
Examples
Run any example:
| Example | Purpose |
|---|---|
basic |
Minimal site with SEO, search, and fused transforms |
quickstart |
Scaffold and build in 10 lines |
multilingual |
Multi-locale site with hreflang and per-locale sitemaps |
plugins |
Full plugin pipeline demo with DepGraph API |
blog |
EAA-compliant accessibility-first blog with dual feeds |
docs |
Documentation portal with schema validation and syntax highlighting |
landing |
Zero-JS landing page with CSP hardening |
portfolio |
Developer portfolio with JSON-LD and Atom feed |
Edge-runtime adapters (v0.0.45)
examples/edge-cloudflare/ and examples/edge-vercel/ are runnable
reference implementations of the ISR + RPC pipeline for the two target
edge runtimes. Each contains a wrangler.toml / vercel.json, the
TypeScript glue (worker.ts, api/[...path].ts), an upload script
for content provisioning (KV / Edge Config), and a smoke-test
harness.
# Cloudflare Workers
# Vercel Edge
Development
CI
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
push, PR | fmt, clippy, test (3 OS), coverage (95% floor), cargo-deny |
document.yml |
push to main | Build and deploy API docs to GitHub Pages |
release.yml |
tag v* |
Cross-platform binaries, GHCR container, crates.io, AUR |
scheduled.yml |
weekly, tag | Multi-OS portability, pa11y a11y, CycloneDX SBOM, benchmarks |
visual.yml |
PR | Playwright screenshots (3 viewports) + axe-core WCAG 2.2 AA |
wasm.yml |
push, PR | Build and test ssg-core + ssg-wasm for wasm32 |
readability-gate.yml |
PR | Flesch-Kincaid audit on docs and content |
See CONTRIBUTING.md for signed commits and PR guidelines.
Security
#![forbid(unsafe_code)]across the entire codebase- CSP build-time extraction: all inline styles and scripts moved to external files with SRI hashes. Zero
unsafe-inline - Path traversal prevention with
..detection and symlink rejection - File size limits and directory depth bounds
cargo auditwith zero advisoriescargo deny-- license, advisory, ban, and source checkscargo vet-- per-crate audit attestation; imports Mozilla Firefox, Bytecode Alliance, and Google trust sets. Seesupply-chain/README.mdCycloneDXSBOM generated as release artifact with Sigstore attestation- SPDX license headers on all source files
- Signed commits enforced via SSH ED25519
See docs/whitepaper/csp-without-compromise.md for the full CSP security architecture.
| Module | Purpose |
|---|---|
accessibility |
WCAG 2.2 AA checker, ARIA validation, decorative image detection, target-size + focus-appearance checks, compliance matrix |
ai |
AI-readiness hooks, alt-text validation, llms.txt / llms-full.txt generation |
assets |
Asset fingerprinting and SRI hash generation |
cache |
Content fingerprinting (FNV-1a) for incremental builds |
cmd |
CLI argument parsing, SsgConfig, input validation |
content |
Content schemas, ContentValidationPlugin, --validate |
csp |
CSP build-time extraction of inline styles/scripts to external files |
depgraph |
Page-to-template dependency graph for incremental rebuilds |
deploy |
Netlify, Vercel, Cloudflare Pages, GitHub Pages adapters |
drafts |
Draft content filtering |
frontmatter |
Frontmatter extraction and .meta.json sidecars |
fs_ops |
Safe file operations with traversal prevention |
highlight |
Syntax highlighting for code blocks |
i18n |
Hreflang injection, per-locale sitemaps, language switcher |
image_plugin |
Responsive <picture> with WebP, srcset generation |
islands |
Web Components with lazy hydration |
livereload |
WebSocket live-reload, CSS HMR, browser error overlay |
llm |
Local LLM pipeline (Ollama), multilingual readability scoring, agentic fix |
logging |
Structured logging configuration |
markdown_ext |
GFM tables, strikethrough, task lists |
og_image |
Auto-generated OG social card SVGs |
pagination |
Pagination plugin for listing pages |
pipeline |
Build orchestration, plugin registration, RunOptions |
plugin |
Plugin trait with lifecycle hooks, PluginManager, PluginCache |
plugins |
MinifyPlugin, ImageOptiPlugin, DeployPlugin |
postprocess |
Sitemap, RSS, Atom, manifest, HTML post-processing fixes |
process |
Directory creation and site processing |
scaffold |
Project scaffolding (ssg --new) |
schema |
JSON Schema generator for configuration |
search |
Full-text search index, modal UI, 28 locale translations |
seo |
SeoPlugin, JsonLdPlugin, CanonicalPlugin, RobotsPlugin |
server |
Development HTTP server |
shortcodes |
youtube, gist, figure, admonition expansion |
stream |
High-performance streaming file processor |
streaming |
Memory-budgeted streaming compilation for large sites |
taxonomy |
Tag and category index generation |
template_engine |
MiniJinja templating engine integration |
template_plugin |
MiniJinja template rendering plugin |
walk |
Shared bounded directory walkers |
watch |
Polling-based file watcher with change classification |
event_watch |
Event-driven file watcher (notify::recommended_watcher, 100 ms debounce) — issue #526 |
hmr |
Component-level Hot Module Replacement over sync WebSocket (tungstenite) with discriminated hmr-css / hmr-html / reload frames — issue #526 |
llm_cache |
Deterministic content-hash-keyed LLM inference cache at target/ssg-cache/llm/ (atomic writes, --no-llm-cache to bypass) — issue #528 |
isr_manifest |
Per-page SHA-256 manifest for Edge ISR adapters (--isr flag) — issue #549 |
view_transitions |
Opt-in View Transitions API client + lazy-hydration emitter (transitions = true) — issue #547 |
rpc_schema |
#[ssg_rpc] JSON-Schema → TypeScript .d.ts emitter — issue #548 |
search_index |
Build-side emitter for ssg-search artifacts (embeddings.bin, model.bin, tokenizer.bin, manifest.json) — issue #545 |
postprocess::edge_headers |
Per-host header emitters (Cloudflare _headers, Netlify _headers, Vercel vercel.json) with PQC TLS guidance — issue #550 |
postprocess::agentic_discovery |
/agents.txt + /.well-known/{ai-plugin.json,mcp.json} emitters — issue #552 |
seo::jsonld::iso20022 |
ISO 20022 schema.org descriptors for regulated financial sites (IBAN/BIC validators) — issue #553 |
audit |
14-gate audit runner (ssg audit) with JSON / JUnit / text output — issue #551 |
head_dom |
Single-walk lol_html-based head metadata extractor + </head> injector — issue #538-540 |
Workspace crates
| Crate | Published | Purpose |
|---|---|---|
ssg |
✓ crates.io | Main library + binary. Imports the other crates. |
ssg-core |
✓ crates.io | WASM-compatible core: markdown compile, frontmatter parse, ContentProvider trait, ISR manifest types. Shared by build + Edge runtimes. |
ssg-wasm |
Internal | wasm32-unknown-unknown entry points for Cloudflare Workers + Vercel Edge (ISR + RPC dispatch). Built via wasm-pack. |
ssg-search |
Internal | Browser-native vector semantic search. Int8-quantised hashed-n-gram embedder by default (model-free, deterministic); opt-in real model2vec-rs encoder. |
ssg-rpc |
Internal | JSON-over-POST RPC dispatch + schemars 1.2 + custom TS emitter. Paired with #[ssg_rpc] proc-macro for zero-config method registration. |
ssg-rpc-macro |
Internal | Proc-macro for #[ssg_rpc] attribute. Registered into a global inventory at compile time. |
License
Dual-licensed under Apache 2.0 or MIT, at your option.
See CHANGELOG.md for release history.