| .github/workflows | ||
| docs | ||
| example | ||
| site | ||
| src | ||
| .gitignore | ||
| action.yml | ||
| build.zig | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| mise.toml | ||
| README.md | ||
| test.sh | ||
ypsilanti
minimal static site generator in zig.
example/ is a demo site you can build and serve to see how everything fits together.
install
requires zig (0.14+).
zig build -Doptimize=ReleaseFast
cp zig-out/bin/ypsilanti /usr/local/bin/
-Doptimize options: Debug (default), ReleaseSafe, ReleaseFast, ReleaseSmall. use ReleaseFast for production, skip the flag for development.
usage
ypsilanti build ./site ./output # build site
ypsilanti serve ./site # dev server on :3000
ypsilanti serve ./site 8080 # custom port
site structure
site/
├── content/ # markdown files → html
├── layouts/ # page templates
├── partials/ # reusable snippets
├── static/ # copied as-is (css, images, fonts)
└── config # optional site config
config
title: example.com
url: https://example.com
author: your name
description: site description
theme: darkode
paginate: 10
nav: home=/, posts=/posts/, tags=/tags/, rss=/feed.xml
front matter
---
title: Hello World
date: 2025-01-09
description: post summary for rss
layout: post
tags: linux, software
categories: technology
draft: false
aliases: /old-post/, /legacy/post.html
---
your content here
title- page title, available as{{title}}date- includes page in rss feeddescription- rss item descriptionlayout- which layout to use fromlayouts/tags- comma-separated tags, used for generated tag pagescategories- comma-separated categories, used for generated category pagesdraft- set totrueto skip the pagealiases/alias- comma-separated local URLs that emit static redirect pages
any key except reserved content, nav_html, and toc is available as {{key}} in templates.
templates
layouts go in layouts/. use {{content}} for the rendered markdown:
<!DOCTYPE html>
<html>
<head><title>{{title}}</title></head>
<body>
{{> header}}
{{{toc}}}
<main>{{{content}}}</main>
</body>
</html>
Template variables are HTML-escaped by default. Variables rendered directly inside href and src attributes are also checked for safe URL schemes. Triple braces render raw HTML only for built-in content and nav_html variables.
partials go in partials/. include with {{> name}}:
<!-- partials/header.html -->
<nav><a href="/">home</a></nav>
markdown
supported:
# headers(h1-h6)**bold**and*italic*[links](url)with safehttp,https,mailto, anchor, or relative URLs`inline code`- fenced code blocks with language class
- basic syntax highlighting spans for common fenced code languages
- unordered lists> blockquotes- pipe tables
- footnotes with
[^id]and[^id]: text - whole-line shortcodes:
figure,youtube,vimeo, andcallout
Headings get generated id attributes and a raw {{{toc}}} template variable.
shortcode examples:
{{< figure src="/img/photo.jpg" alt="Photo" caption="A caption" >}}
{{< youtube dQw4w9WgXcQ >}}
{{< vimeo 123456789 >}}
{{< callout type="warning" title="heads up" text="important note" >}}
error pages
create content/404.md for custom 404 pages. works in dev server and most static hosts.
pages are generated with clean URLs: content/about.md becomes about/index.html and is served at /about/.
rss + sitemap
auto-generated on build:
sitemap.xml- all pagesfeed.xml- pages withdate:front matterposts/- dated posts sorted newest first, paginated withpaginate:tags/andcategories/- taxonomy indexes and paginated term pages
set base url in site/config with url:. site/url is still supported as a fallback.
link checking
build validates internal href and src links after writing pages and static files. Root-relative links, relative links, and fragment anchors must point to generated output or the build fails.
deploy
github pages (recommended)
ypsilanti ships a GitHub Action, so a full deploy is one uses: line. Copy
docs/github-pages.yml into your site repo as
.github/workflows/pages.yml, then set Settings → Pages → Source to GitHub
Actions. The core of it:
- uses: actions/checkout@v4
- uses: maxf1eld/ypsilanti@main # pin to a tag or SHA for stability
with:
source: ./site # your site source dir
- uses: actions/upload-pages-artifact@v3
with:
path: ./_site
The action builds ypsilanti and your site with no local Zig install needed.
Internal links are root-relative (/about/), so deploy at a root domain —
a user/org page (you.github.io) or a custom domain. A project page
(you.github.io/repo/) serves under a subpath and will break those links.
manual / other hosts
Build locally and push the output anywhere that serves static files (Netlify, Cloudflare Pages, S3, a plain web server):
ypsilanti build ./site ./docs
git add docs && git commit -m "build" && git push
dev workflow
ypsilanti serve ./site
opens dev server with live reload. edit any file in content/, layouts/, partials/, or static/ and browser refreshes automatically.
tests
./test.sh
contributing
Contributions are welcome. Run ./test.sh before opening a pull request; CI
runs the same suite. See CONTRIBUTING.md for more.
license
MIT — see LICENSE.