Styx
5 min read
Nix-based static site generator. Sites are defined entirely in Nix expressions; content is written in Markdown, AsciiDoc, or native Nix and rendered via customizable themes.
Key Features
• All templates, logic, and data use the same Nix expression language
• Efficient incremental builds via Nix's caching (only modified content is rebuilt)
• Minimal dependencies — only Nix required
• Type-checked configuration via NixOS module system
• Automatic SASS/SCSS compilation
• Embedded Nix expressions inside markup files ({{ expr }})
• Multipage / paginated content via mkSplit
• Taxonomy system (mkTaxonomyData / mkTaxonomyPages)
• Built-in link checker (styx linkcheck)
Limitations
• Markup conversion can be slow (mitigated by caching on rebuilds)
• Requires learning the Nix expression language
Installation
bash
# Temporary shell
nix shell github:styx-static/styx
Quick Start
bash
styx new site my-site
cd my-site
styx preview # serve at http://127.0.0.1:8080
styx doc # open full HTML documentation in browser
Preview a bundled theme without creating a site:
bash
styx preview-theme showcase
CLI Reference
Generic Flags
| Flag | Description |
|---|---|
--help | Display help |
--version | Display version |
--in DIR | Run command in specified directory |
--file FILE | Use a custom file instead of site.nix |
--drafts | Include draft content in build |
--show-trace | Show debug trace on failure |
--arg NAME VALUE | Pass argument to main function |
--argstr NAME VALUE | Pass string argument to main function |
-I PATH | Add path to Nix expression search path |
Commands
| Command | Description |
|---|---|
styx new site NAME | Create a new site in current directory |
styx new site NAME --in DIR | Create site in DIR/NAME |
styx new theme NAME --in DIR | Create a new theme skeleton |
styx build | Build site to public/ directory |
styx build --out DIR | Build to custom output directory |
styx store-path | Return the Nix store path of the built site |
styx preview | Start local server at 127.0.0.1:8080 |
styx preview --port 9090 | Start server on custom port |
styx preview-theme NAME | Preview a bundled theme |
styx live | Auto-rebuilding live preview (quit with q) |
styx serve | Build and serve site on port 8080 |
styx serve --detach | Serve in background |
styx linkcheck | Validate all links in the built site |
styx doc | Open HTML documentation in browser |
styx site-doc | Generate and display site-specific docs |
styx gen-data | Generate sample data in ./data |
styx theme-path NAME | Print the store path of a bundled theme |
styx deploy --init-gh-pages | Initialize gh-pages branch for GitHub Pages |
styx deploy --gh-pages | Build and deploy to GitHub Pages |
Project Structure
A minimal site only needs site.nix. The styx new command scaffolds:
my-site/
├── conf.nix # site configuration
├── default.nix # allows building with plain `nix build`
├── site.nix # core site logic
├── data/ # content (Markdown, AsciiDoc, Nix files)
└── themes/ # custom/local themes
site.nix Structure
A site.nix is conventionally divided into sections:
nix
# 1. Init — load styx library
# 2. Themes — declare themes and load their assets/conf
# 3. Data — load content files with loadFile / loadDir
# 4. Pages — declare pages (path, template, layout)
# 5. Site — call mkSite with the pages list
Every page must declare three attributes:
| Attribute | Description |
|---|---|
path | Output file path, must start with / (e.g. "/index.html") |
template | Function page -> page that processes the page data |
layout | Function page -> string that wraps the template output |
Generation evaluates page.layout (page.template page) for each page.
Configuration (conf.nix)
Configuration is merged from three sources (highest priority last):
1. Theme's own conf.nix
2. Site root conf.nix
3. extraConf passed via CLI
conf.nix can be a plain attribute set or a function returning one (receives { lib }).
The only required field is siteUrl — must not end with /:
nix
{
siteUrl = "https://example.com";
theme.site.title = "My Site"; # override theme config
}
Content / Data
Loading Content
nix
data = {
posts = loadDir { dir = ./data/posts; }; # list of attr sets
about = loadFile { file = ./data/pages/about.md; };
};
loadFile / loadDir automatically:
• Parse YAML front matter (between --- delimiters)
• Extract introductions
• Evaluate embedded {{ nix }} expressions
Supported Formats
| Format | Use case | Processor |
|---|---|---|
| Markdown | Simple posts and pages | Pandoc → content attr |
| AsciiDoc | Complex documents with rich formatting | Asciidoctor |
| Nix | Complex data structures, parameterized data | Native |
Drafts
Mark a file as a draft in front matter:
yaml
---
draft: true
---
Drafts are excluded unless --drafts flag is passed or renderDrafts = true in conf.
Taxonomies
nix
taxonomyData = mkTaxonomyData { data = posts; taxonomies = [ "tags" "author" ]; };
taxonomyPages = mkTaxonomyPages { data = taxonomyData; ... };
Page Types
| Type | Function | Description |
|---|---|---|
| Simple | — | Single page with required attributes |
| Data-attached | // | Merge external data into a page |
| Split/Paginated | mkSplit | Distribute a list across multiple pages with pagination metadata |
| Multipages | mkMultipages | Hierarchical nested page sets |
| Page list | mkPageList | Produces list (no subpages) and pages (all) attributes |
| Taxonomy | mkTaxonomyPages | Index + term pages from taxonomy data |
Themes
Available Bundled Themes
| Theme | Description |
|---|---|
agency | Business / corporate |
generic-templates | Flexible reusable templates |
ghostwriter | Content-focused, readable |
hyde | Sidebar layout |
nix | Minimalist |
orbit | Modern / portfolio |
showcase | Portfolio / showcase |
Using Themes in site.nix
nix
themes = [ pkgs.styx-themes.hyde ]; # official theme
# or
themes = [ ./themes/my-theme ]; # local theme
Items at the beginning of the list have lower priority; later entries override earlier ones — useful for layering a customization theme on top of a base theme.
Creating a Theme
bash
styx new theme my-theme --in ./themes
Scaffold:
my-theme/
├── conf.nix # typed or untyped configuration interface
├── meta.nix # metadata — must include `id` attribute
├── files/ # static assets copied to generated site
├── templates/ # template .nix files
└── lib.nix # (optional) custom functions
Theme config is merged into conf.theme and can be overridden from the site's conf.nix.
Deployment
GitHub Pages
bash
styx deploy --init-gh-pages # one-time: creates gh-pages branch
styx deploy --gh-pages # build + commit to gh-pages branch
Amazon S3
bash
aws s3 sync $(styx store-path) s3://<bucket-name>/