Documentation
« A documentation about the documentation inside the documentation. »
This guide, aimed at contributors working on NixKraken documentation, explains how it is structured and built.
Overview
The documentation is using VitePress to generate a static website from the Markdown content located inside the docs directory. Its canonical build path uses a Nix derivation.
A GitHub Actions workflow, available at .github/workflows/deploy-docs.yml, builds and deploys the website to GitHub Pages.
The docs directory defines several files and directories, each with unique responsibilities:
.
├── .vitepress # VitePress theme and config
├── @types # TypeScript types declarations
├── patches # NPM package patches
├── src # Markdown content
├── default.nix # Nix build derivation
├── generate_docs.py # Reference pages builder
├── options-json.nix # Module options evaluator
├── package.json # NPM package configuration
└── package-lock.json # NPM package lockfileINFO
All paths and commands referenced in the rest of this document are relative to the docs directory, unless stated otherwise.
Local Development
Prerequisites
For local development, NodeJS is required to run VitePress. You can either install it globally, or use the provided Nix development shell.
Once NodeJS is installed, the npm command should be available. Use it to install VitePress and the dependencies required by the documentation:
$ npm installRunning
To serve the documentation website locally, for development purposes, run the following command:
$ npm run devThe documentation will be served at http://localhost:5173.
Any change to documentation files will trigger a live or full reload, depending on the content changed.
Building
To build the documentation, run the following command:
$ npm run buildThe documentation will be built in the .vitepress/dist directory.
Content Authoring
Structure
The documentation pages are generated from Markdown files located in the src directory.
Each of these files is built as a single HTML page and is served at the same URL location as its location in the filesystem, relative to the src directory.
EXAMPLE
A file stored in src/foo/bar.md would be served from /foo/bar.
To further organize documentation content and improve navigation, we use three distinct categories of documentation:
- Guide: installation instructions and how-tos aimed, primarily aimed at users
- Reference: module options reference, aimed at end-users and contributors
- Contribute: explanations about various aspects of the project, aimed at contributors
These categories are shown in the documentation navigation bar and are separated in different directories:
src
├── contrib # Contributors documentation
├── guide # User guides
└── reference # Options documentationGenerated Content
Throughout the documentation, there are multiple special markers which are used to generate content at build time. This process avoids manual maintenance of documentation directly originating from code, effectively avoiding update omissions.
Here is a list of currently used markers:
| Marker | Location | Replacement |
|---|---|---|
CACHED_COMMIT_LIST | src/guide/user/caching.md | List of nixpkgs cached commits |
GK_<pkg>_USAGE | src/contrib/pkgs | Usage output of <pkg> command |
THEMES_LIST | src/guide/user/theming.md | List of bundled themes |
CURRENT_VERSION | Multiple places | Current NixKraken version |
Additionally, most files located in the reference directory are automatically generated from NixKraken module's evaluated options. Identifying them is easy since they include a header with an explicit warning message:
---
# This file is automatically generated. DO NOT EDIT MANUALLY.
---These files are generated through CI, whenever there is a change in the repository.
TIP
For further details on this generation process, refer to the specific section about the options documentation builder.
Conventions
We try to follow the conventions below to keep the documentation homogenous, digestable-(ish) and maintainable, while being the most complete possible:
use APA-style headings casing
avoid use of contractions
- this is valid:
it is - this is not:
it's
- this is valid:
use reference-style Markdown links
- this is valid:
[some link][link-ref] - this is not:
[some link](https://example.org)
- this is valid:
store link references at the top of Markdown files
md[link-ref]: https://example.orgkeep the list of link references alphabetically ordered
link to official stable documentations when relevant
use a consistent naming for link references
Documentation Naming pattern Nix reference [nix-manual<-topic?>]NixOS reference [nixos-manual<-topic?>]NixOS wiki [nixos-wiki<-topic?>]nixpkgs reference [nixpkgs-manual<-topic?]Home Manager reference [hm<-topic?>]Home Manager options reference [hm-opt<-option?>]Home Manager NixOS options reference [hm-nixos-opt<-option?>]Nix tutorials and guides [nixdev<-topic?>]when linking to heading IDs, start the link reference with
loc-when linking to other documentation pages, start the link reference with
doc-do not be shy on cross-reference links
Alerts and Callouts
VitePress supports custom containers, which can be used to render alerts/callouts throughout the documentation.
We customized them a bit by adding a FontAwesome icon before the title, using some CSS. See the VitePress customization section for further details.
::: info
Useful information that users should know, even when skimming content.
:::
::: tip
Helpful advice for doing things better or more easily.
:::
::: warning
Urgent info that needs immediate user attention to avoid problems.
:::
::: danger
Advises about risks or negative outcomes of certain actions.
:::INFO
Useful information that users should know, even when skimming content.
TIP
Helpful advice for doing things better or more easily.
WARNING
Urgent info that needs immediate user attention to avoid problems.
DANGER
Advises about risks or negative outcomes of certain actions.
Images and Assets
If there is a need to use images and/or assets, they should be added in a directory called assets and located at the same level as their consumer. For example, if an image is needed in the src/contrib/docs.md file, the source images should be stored in the src/contrib/assets directory.
Additional assets, like CSS or JavaScript files, should be stored in the .vitepress/theme directory. This is further covered in the VitePress customization section.
VitePress Specifics
INFO
We use VitePress alpha version 2.
Configuration
VitePress configuration is split in two locations:
src/config.ts: "content" configuration like sidebars, navigation bar, footer, etc..vitepress/config.mts: behavior configuration like site config, markdown plugins, search provider, etc.
This setup is replicating VitePress' own way of dealing with configuration for their documentation.
TIP
See the official VitePress reference for further details about configuration options and behavior.
Customization
VitePress allows to customize the default theme through the .vitepress/theme/index.ts file, from which other files can be imported to further customize VitePress look and feel.
Additionally, VitePress allows to customize Markdown parsing process, through the markdown site config option and markdown-it plugins.
The documentation takes advantage of these to introduce several custom behaviors, which are detailed in the following sections.
Custom CSS
Some minor CSS customizations are brought, although the main ones are:
- home page customizations (title and feature icons color, logo shadow)
- custom
<kbd>HTML tag rendering, based on this blog post - automatic FontAwesome icon on callouts
Figure captions
This feature is implemented with the markdown-it-implicit-figures plugin, which renders images as <figure> HTML tags with a <figcaption>.
There is no bundled CSS styling, so we added automatically numbered and centered figure captions.
Example:
Mermaid.js Support
Mermaid.js is a JavaScript library that renders diagrams from markdown-like text. This documentation uses Mermaid to illustrate NixKraken concepts.
To add a Mermaid diagram to the documentation, use a fenced code block with the mermaid syntax:
flowchart TD
start["Is NixKraken awesome?"]
yes["Yes it is!"]
what["Say what?"]
start --->|yes| yes
start --->|no| whatWhich renders:
By default, VitePress does not support Mermaid diagrams rendering. There are a few solutions available in the wild, but none were good enough, so we implemented a custom solution based only on the official library.
This is further detailed in the following discussion on VitePress' GitHub.
Options Documentation Builder
Thanks to the self-describing nature of NixOS module options, we can leverage this information to auto-generate reference documentation for module options.
This is the role of the generate_docs.py script, which automatically creates Markdown documentation files from a JSON representation of NixKraken module options.
The script reads this JSON file from command-line arguments to:
- process and categorize options into "groups" matching known submodules (like
datetime,git,gpg,profiles, etc.) - convert each option's metadata (
description,type,defaultvalue,examples) into formatted Markdown documentation
The grouping logic uses string prefix matching to determine which category each option belongs to, with special handling for nested profiles options and a fallback root group for ungrouped items.
For each group, the script generates a separate Markdown file in an organized directory structure, with special handling of profile-specific options (matching the pattern profiles.*.*) which are placed in a profiles subdirectory.
Each generated file includes formatted sections for each option with its:
- name
- description
- scope (profile-specific or global option)
- type information
- valid values extracted from type information, if any
- default value
- optional example
Running
Although the builder script is meant to be run from CI, it can be useful to run it whenever it gets updated or when module options documentation changes.
To run it, we first need to generate the module options JSON representation:
# Using new Nix commands
$ nix build -f docs/options-json.nix# ...or classic Nix commands
$ nix-build -f docs/options-json.nixThis command will generate an options.json file in the result directory, which we can use as input to the builder script:
$ ./docs/generate_docs.py result/options.json docs/src/referenceINFO
docs/src/reference is the output directory.
Nix Derivation
The Nix derivation, located in the default.nix file, is the canonical way to build and package the documentation. It uses the buildNpmPackage builder.
At its core, this derivation is responsible for generating and providing all the necessary content to build the final documentation from the docs source directory, which can then be deployed to a hosting service or served locally.
To build it, use the following command:
# Using new Nix commands
$ nix build '.#docs'# ...or classic Nix commands
$ nix-build ./docsTIP
If using classic Nix commands, make sure to use at least nixpkgs 25.05:
$ nix-build ./docs -I nixpkgs=https://github.com/nixos/nixpkgs/archive/nixos-25.05.tar.gzProviding JSON Module Options Representation
Since the options documentation builder needs to be provided with a JSON representation of the module options in order to generate the reference documentation, the Nix derivation:
- loosely evaluates (
config._module.check = false) the actual module code usinglib.evalModules - pass the evaluated module
optionsattributes tonixosOptionsDocwhich generates, among other formats, a JSON representation of the module options
This JSON representation is then passed down to the options documentation builder to actually generate the reference documentation for module options.
For debugging purposes, here is how to generate the module options JSON representation:
# Using new Nix commands
$ nix build -f options-json.nix# ...or classic Nix commands
$ nix-build options-json.nixOnce run, the JSON options file will be located in result/options.json.
Replacing Special Markers
As mentioned in the generated content section, several markers are consumed by this derivation to generate dynamic documentation content, using the substituteInPlace utility function:
- the
CACHED_COMMIT_LISTmarker is replaced by a Markdown list generated from the GitKraken cached versions - the
GK_<pkg>_USAGEmarkers are replaced by running helper packages with the--helpflag and using the output as replacement - the
THEMES_LISTmarker is replaced by a Markdown table describing all bundled themes - the
CURRENT_VERSIONmarker is replaced by the content of theversion.txtfile