The AI-native static site generator (SSG) with executable code blocks & more, inspired by Zola and Quarto.
crates/
zorto-core/ # Pure library: site model, build pipeline, rendering
zorto-cli/ # CLI binary + preview server (published as "zorto")
zorto-webapp/ # HTMX CMS webapp (feature-gated, under development)
zorto-app/ # Desktop app (future, stubbed)
zorto-py/ # PyO3 bindings (own workspace, built by maturin)
py/zorto/ # Python package wrapper
zorto-corehas no axum/tokio/clap deps — pure library with only filesystem I/Ozorto-clicrate name iszorto(the published binary) with optional features:webapp,appzorto-pyis excluded from the workspace (cdylib, built by maturin)
Crates.io: zorto-core, zorto. PyPI: zorto. Installed binary: zorto.
bin/build # Build all (Rust + Python)
bin/build-rs # Build Rust workspace
bin/build-py # Build Python bindings (maturin develop)
bin/check # Run all checks (format, lint, test)
bin/check-rs # Rust checks (fmt, clippy, machete, deny, test)
bin/check-py # Python checks (ruff, ty)
bin/format # Format all code
bin/test # Run all tests
bin/install # Install CLI (Rust + Python)
bin/bump-version # Bump version (--patch, --minor (default), --major)Rust checks: cargo fmt -- --check, cargo clippy --all-targets --all-features --workspace -- -D warnings, cargo machete, cargo deny check, cargo test --all-targets --all-features --workspace
Python checks: ruff check ., ruff format --check ., ty check
The website/ directory is the zorto.dev project site, built with zorto itself.
website/bin/build # Build the website with uv-managed executable-code deps
bin/preview # Build + preview with --sandbox . (uses cargo run)
website/bin/preview # Same thing (delegates to bin/preview)Important: The website uses content_dirs to pull in ../docs and shortcodes like configref that reference files outside the website directory (e.g. ../crates/). Always use --sandbox . (repo root) when building:
cargo run -p zorto -- --root website --sandbox . build
cargo run -p zorto -- --root website --sandbox . preview --openNever run zorto build directly inside website/ — it will fail with sandbox errors. Use bin/preview or pass --sandbox . from the repo root.
Netlify deploys for zorto.dev are intentionally KISS: configure the Netlify UI command as curl -LsSf https://dkdc.sh/zorto/install.sh | sh && ./bin/build with website as the base directory. That runs website/bin/build; when NETLIFY=true, it uses the installed zorto binary from PATH and does not compile Rust on the deploy runner.
- DO NOT depend on any dkdc-* packages. This is a standalone open source project.
- do clone Zola & Quarto (and any other repos) into the .gitignored 'external' directory and use them as references for how to implement the features in this project.
- Python distribution (via PyO3/maturin) is a hard requirement. The
crates/zorto-py/bindings andpy/zorto/wrapper must be maintained. - Search and data app direction: DuckDB only. Public site data should ship as
.ddbfiles and browser runtime should query them with DuckDB-Wasm. Do not add new SQLite/sql.js search paths.
- site authors (config, templates, theme frontmatter): trusted. They own the build environment — Python code blocks execute with their credentials.
- post authors (markdown bodies, shortcode args): partly trusted in multi-author setups. Shortcode validators (
is_safe_css_length, class allow-list, etc.) treat this as the untrusted boundary. - end readers (browser): fully untrusted outputs — any path from author content to executed JS/CSS in their browser must be inspected (XSS through viz specs, CSS injection through shortcode args, theme URL injection, CDN supply chain).
- Python code blocks execute at build time in the author's venv — by design, NOT a sandbox.
- Sentence case for headings in documentation and on the website. Zorto is an independent open source project — it does NOT follow dkdc's all-lowercase brand style.
- "Zorto" (capitalized) in documentation prose;
zortofor commands, code, URLs. - built-in themes:
zorto,dkdc,default,ember,forest,ocean,rose,slate,midnight,sunset,mint,plum,sand,arctic,lime,charcoal. All feature-gated Cargo features (default: all enabled). Python builds always include all themes. Every theme supports both light and dark mode via[data-theme="light"]CSS variable overrides.
The following files contain prose built up over time that belongs to the project owner. DO NOT rewrite, reword, or "improve" them without the owner's explicit sign-off on the actual new text BEFORE shipping:
README.md: top paragraph (hero / tagline), install copy, positioning.website/config.toml:description,hero_subtitle,hero_title, feature carddescriptionfields.website/content/_index.md(the home page body).- Any content under
website/content/where the owner is listed asauthor.
Additive changes (new sections below the hero, new feature cards appended, new linked pages) are fine. Edits TO existing prose are not; revert-reviews are costly. When in doubt: propose the diff in channel (bus or iMessage), ship only after explicit approval of the specific text.
zorto references Zola's MIT-licensed code as a design guide. The reference copy in external/zola/ must stay at tag v0.21.0 — this is the last MIT-licensed release. Starting at v0.22.0, Zola switched to EUPL which is incompatible with our MIT license. Do NOT checkout, pull, or reference any Zola code beyond v0.21.0.