Skip to content

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:

txt
.
├── .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 lockfile

INFO

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:

sh
$ npm install

Running

To serve the documentation website locally, for development purposes, run the following command:

sh
$ npm run dev

The 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:

sh
$ npm run build

The 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:

txt
src
├── contrib    # Contributors documentation
├── guide      # User guides
└── reference  # Options documentation

Generated 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:

MarkerLocationReplacement
CACHED_COMMIT_LISTsrc/guide/user/caching.mdList of nixpkgs cached commits
GK_<pkg>_USAGEsrc/contrib/pkgsUsage output of <pkg> command
THEMES_LISTsrc/guide/user/theming.mdList of bundled themes
CURRENT_VERSIONMultiple placesCurrent 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:

yaml
---
# 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:

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.

md
::: 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:

md
![A random cat image](https://cataas.com/cat 'A random cat image')
A random cat image

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:

mmd
flowchart TD
  start["Is NixKraken awesome?"]
  yes["Yes it is!"]
  what["Say what?"]

  start --->|yes| yes
  start --->|no| what

Which renders:

flowchart TD start["Is NixKraken awesome?"] yes["Yes it is!"] what["Say what?"] start --->|yes| yes start --->|no| what

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, default value, 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:

sh
# Using new Nix commands
$ nix build -f docs/options-json.nix
sh
# ...or classic Nix commands
$ nix-build -f docs/options-json.nix

This command will generate an options.json file in the result directory, which we can use as input to the builder script:

sh
$ ./docs/generate_docs.py result/options.json docs/src/reference

INFO

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:

sh
# Using new Nix commands
$ nix build '.#docs'
sh
# ...or classic Nix commands
$ nix-build ./docs

TIP

If using classic Nix commands, make sure to use at least nixpkgs 25.05:

sh
$ nix-build ./docs -I nixpkgs=https://github.com/nixos/nixpkgs/archive/nixos-25.05.tar.gz

Providing 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 using lib.evalModules
  • pass the evaluated module options attributes to nixosOptionsDoc which 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:

sh
# Using new Nix commands
$ nix build -f options-json.nix
sh
# ...or classic Nix commands
$ nix-build options-json.nix

Once 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_LIST marker is replaced by a Markdown list generated from the GitKraken cached versions
  • the GK_<pkg>_USAGE markers are replaced by running helper packages with the --help flag and using the output as replacement
  • the THEMES_LIST marker is replaced by a Markdown table describing all bundled themes
  • the CURRENT_VERSION marker is replaced by the content of the version.txt file

Released under the MIT License