Rustipo provides the following commands.
Published install:
cargo install rustipoPrebuilt binaries are also attached to each GitHub release for:
x86_64-unknown-linux-gnux86_64-apple-darwinaarch64-apple-darwinx86_64-pc-windows-msvc
Download the matching archive from the GitHub releases page, extract it, and place rustipo
or rustipo.exe on your PATH.
Local development from the repository:
cargo install --path .or
cargo run -- --helprustipo new my-site
cd my-site
rustipo palette list
rustipo palette use catppuccin-mocha
rustipo dev
rustipo buildProject validation:
rustipo checkAnalytics configuration is opt-in. Rustipo uses a generic analytics config model:
[site.analytics]
domain = "docs.example.com"
script_src = "https://stats.example.com/js/script.js"Built-in themes render the analytics snippet automatically when configured.
Theme discovery:
rustipo theme list
rustipo theme install owner/repoValidates project inputs without writing build output.
Current behavior:
- Loads and validates
config.toml - Loads the active theme and selected palette
- Validates configured favicon and local font assets
- Parses Markdown content and frontmatter
- Excludes drafts and future-dated content using production rules
- Renders pages through the theme templates
- Validates internal Markdown links against generated routes and deep links when possible
- Validates rendered route/output collisions
- Validates generated
palette.csswould not collide with site or theme assets - Validates optional SCSS inputs when
themes/<theme>/static/style.scssorstatic/custom.scssare used - Validates theme and user static asset paths would not collide
- Exits with non-zero status when validation fails
Creates a new starter Rustipo site project directory.
Example:
rustipo new my-siteCurrent behavior:
- Creates starter
content/,static/, andthemes/default/structure - Writes starter
config.tomland Markdown pages - Writes starter
static/favicon.svgand configures favicon inconfig.toml - Writes required default theme templates and starter CSS
- Starter CSS includes default markdown prose styling (headings, spacing, code, links, tables, blockquotes)
- Fails if target directory already exists
Builds once, starts the local server, and watches for changes.
Example:
rustipo devrustipo dev --host 0.0.0.0 --port 4000Current behavior:
- Runs the same local workflow as
rustipo serve --watch - Performs an initial build before serving
- Includes drafts and future-dated content in local preview builds
- Rebuilds on file changes and triggers live reload after successful rebuilds
- Uses the same default address as
serve:127.0.0.1:3000
Builds site content into static output (dist/).
Current behavior:
- Loads and validates
config.toml - Loads active theme from
themes/<theme>/ - Loads selected palette from built-in palettes or local
palettes/<palette>.toml - Resolves theme inheritance chain when
extendsis used intheme.toml - Validates required templates across the resolved theme chain
- Discovers Markdown files from
content/ - Parses frontmatter, validates date format (
YYYY-MM-DD), and excludes drafts and future-dated content from production output - Converts Markdown to HTML
- Renders supported shortcodes in Markdown content
- Injects page-scoped script and stylesheet assets declared by supported shortcodes
- Applies syntax highlighting to fenced code blocks
- Parses inline and block math nodes in Markdown
- Parses GitHub-style alert blockquotes in Markdown
- Wraps standalone Markdown images in responsive figure markup
- Generates processed image derivatives requested through
resize_image(...) - Renders
mermaidfenced blocks as diagrams - Injects Mermaid runtime only on pages that contain Mermaid blocks
- Injects KaTeX runtime only on pages that contain math content
- Renders pages through theme templates
- Resolves favicon links for template context (
site_favicon*variables) - Fails with a readable error when configured favicon path is missing in
static/ - Resolves custom font families from
site.typography - Validates configured local font-face assets from
static/or inherited themestatic/directories - Injects
@font-faceCSS only when configured font faces are present - Validates internal Markdown links against generated routes and deep links when possible
- Exposes style context from
config.tomlto templates (site_style.*):site.layout.content_widthsite.layout.top_gapsite.layout.vertical_align(centerorstart, default:center)site.typography.line_heightsite.typography.body_fontsite.typography.heading_fontsite.typography.mono_font
- Exposes
site_font_faces_cssto templates for optional font-face injection - Exposes
site_analytics_head_htmlto templates for opt-in analytics snippet output - Auto-includes
static/custom.cssin template context when present (site_has_custom_css) - Compiles optional
themes/<theme>/static/style.scssintodist/style.css - Compiles optional
static/custom.scssintodist/custom.css - Writes rendered pages to
dist/using pretty URL output paths - Writes generated palette variables to
dist/palette.css - Fails with a readable error if generated
palette.csswould collide with a user/theme asset - Fails with readable error on duplicate rendered output route collisions
- Copies theme and user static assets into
dist/ - Applies child-over-parent precedence when inherited themes provide the same template/asset path
- Fails on static asset path collisions
- Generates section index pages for
/blog/and/projects/ - Generates taxonomy listing pages at
/tags/and/tags/<tag>/from blog post tags - Generates RSS feed at
dist/rss.xmlfrom dated blog posts - Generates sitemap at
dist/sitemap.xmlfrom rendered site routes - Generates search index at
dist/search-index.jsonfrom site content - Generates
dist/robots.txtwith default crawler guidance and sitemap location - Generates
dist/404.htmlusingtemplates/404.htmlwhen present, orpage.htmlas a fallback - Uses a CDN-backed Mermaid ESM runtime in v1
- Uses a CDN-backed KaTeX ESM runtime in v1
Serves built static output locally.
Example:
rustipo serve --host 0.0.0.0 --port 4000rustipo serve --watchCurrent behavior:
- Serves files from
dist/ - Default address:
127.0.0.1:3000 - Supports custom host/port via
--hostand--port - Supports watch mode with
--watch(rebuilds on file changes) - In watch mode, preview builds include drafts and future-dated content
- In watch mode, injects live-reload script into HTML responses and auto-refreshes browser after successful rebuild
- In watch mode, skips rebuild when file content hash is unchanged (reduces no-op save rebuild noise)
- Prints local URL on startup
- Returns readable error if
dist/does not exist
Lists available themes.
Current behavior:
- Lists built-in themes shipped with Rustipo
- Lists local themes from
themes/*/theme.tomlwhen present - Prints selectable theme ID, name, version, description, and source (
built-inor local directory name) - Theme IDs use lowercase kebab-case; variant themes should use
family-variant
Config example:
theme = "default"Current built-in themes:
atlasjournal
Lists available palettes.
Current behavior:
- Lists built-in palettes shipped with Rustipo
- Lists local palettes from
palettes/*.tomlwhen present - Prints palette ID, name, description, and source (
built-inorlocal)
Config example:
palette = "catppuccin-mocha"Current built-in Catppuccin flavors:
catppuccin-lattecatppuccin-frappecatppuccin-macchiatocatppuccin-mocha
Additional built-in palettes:
defaultdraculagruvbox-darktokyonight-stormtokyonight-moon
Updates config.toml to use the selected palette.
Example:
rustipo palette use catppuccin-mochaCurrent behavior:
- Validates the palette exists before updating config
- Writes or updates the top-level
palette = "..."key inconfig.toml - Prints the selected palette ID after updating
Installs a theme into themes/.
Examples:
rustipo theme install fcendesu/rustipo-themerustipo theme install https://github.com/fcendesu/rustipo-themerustipo theme install fcendesu/rustipo-theme --name cyberpunkCurrent behavior:
- Accepts GitHub shorthand (
owner/repo) or GitHub URL - Also accepts local git repository path (useful for local development/testing)
- Clones repository into
themes/<name>/(or inferred repo name) - Removes cloned
.gitmetadata from installed theme directory - Validates required theme contract after install
- Fails with readable errors on clone/validation conflicts
Generates a GitHub Actions workflow for deploying dist/ to GitHub Pages.
Example:
rustipo deploy github-pagesrustipo deploy github-pages --forceCurrent behavior:
- Writes
.github/workflows/deploy-pages.yml - Workflow installs Rustipo from crates.io with
cargo install rustipo --locked - Workflow runs
rustipo buildand deploysdist/using Pages actions - Refuses to overwrite existing workflow unless
--forceis provided
Generates a GitHub Actions workflow for deploying dist/ to Cloudflare Pages using Wrangler.
Example:
rustipo deploy cloudflare-pagesrustipo deploy cloudflare-pages --forceCurrent behavior:
- Writes
.github/workflows/deploy-cloudflare-pages.yml - Workflow installs Rustipo from crates.io with
cargo install rustipo --locked - Workflow runs
rustipo build - Workflow deploys
dist/withcloudflare/wrangler-action - Expects these repository settings before the workflow can run:
- secret:
CLOUDFLARE_API_TOKEN - secret:
CLOUDFLARE_ACCOUNT_ID - variable:
CLOUDFLARE_PAGES_PROJECT
- secret:
- Refuses to overwrite existing workflow unless
--forceis provided
If you prefer Cloudflare Pages Git integration instead of direct uploads, use:
- build command:
cargo install rustipo --locked && rustipo build - build output directory:
dist
Generates a GitHub Actions workflow for deploying dist/ to Netlify with Netlify CLI.
Example:
rustipo deploy netlifyrustipo deploy netlify --forceCurrent behavior:
- Writes
.github/workflows/deploy-netlify.yml - Workflow installs Rustipo from crates.io with
cargo install rustipo --locked - Workflow installs Netlify CLI with
npm install -g netlify-cli - Workflow runs
rustipo build - Workflow deploys
dist/withnetlify deploy --dir=dist --prod - Expects these repository secrets before the workflow can run:
NETLIFY_AUTH_TOKENNETLIFY_SITE_ID
- Refuses to overwrite existing workflow unless
--forceis provided
You can control default layout behavior without editing theme CSS:
[site.layout]
content_width = "98%"
top_gap = "2rem"
vertical_align = "center" # "center" (default) or "start"
[site.typography]
line_height = "1.5"
body_font = "\"Inter\", sans-serif"
heading_font = "\"Fraunces\", serif"
mono_font = "\"JetBrains Mono\", monospace"
[[site.typography.font_faces]]
family = "Inter"
source = "/fonts/inter.woff2"
weight = "400"
style = "normal"vertical_align = "center"keeps the classic vertically centered intro layout.vertical_align = "start"aligns content to the top while keeping horizontal centering.body_font,heading_font, andmono_fontlet you swap font stacks without editing theme CSS.font_faceslets you ship local fonts fromstatic/or inherited theme assets.- The default theme now ships a fuller editor-like heading scale (
h1-h6) and tighter prose spacing.
Theme and palette example:
theme = "default"
palette = "tokyonight-storm"