Styx
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
# Temporary shell
nix shell github:styx-static/styxQuick Start
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 browserPreview a bundled theme without creating a site:
styx preview-theme showcaseCLI 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:
# 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 listEvery 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):
- Theme’s own
conf.nix - Site root
conf.nix extraConfpassed 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 /:
{
siteUrl = "https://example.com";
theme.site.title = "My Site"; # override theme config
}Content / Data
Loading Content
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:
---
draft: true
---Drafts are excluded unless --drafts flag is passed or renderDrafts = true in conf.
Taxonomies
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
themes = [ pkgs.styx-themes.hyde ]; # official theme
# or
themes = [ ./themes/my-theme ]; # local themeItems 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
styx new theme my-theme --in ./themesScaffold:
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
styx deploy --init-gh-pages # one-time: creates gh-pages branch
styx deploy --gh-pages # build + commit to gh-pages branchAmazon S3
aws s3 sync $(styx store-path) s3://<bucket-name>/