Home / Alt manpages / hugo-gen-chromastyles(1)

  • hugo-gen-chromastyles(1)
  • User command
  • linux

Generate and Install Hugo's Chroma CSS Safely

Your code blocks render with no colour because noClasses is off and nobody generated a stylesheet, and hugo gen chromastyles fixes that in one line. This walks through generating it, checking it, and installing it without destroying whatever stylesheet is already there. Allow about fifteen minutes. You need Hugo 0.123.7 or a nearby release, a site using class-based highlighting, and write access to its asset directory.

This guide describes the installed package on this machine: Hugo 0.123.7, built as the Ubuntu package 0.123.7-1ubuntu0.3+esm2. Later Hugo releases have renamed some options, so check the installed help if your version differs.

1. Check the command and the highlighting mode

Confirm first that the binary you are about to run is the one from your installed package. This is read-only and needs no elevated privileges:

$ command -v hugo
/usr/bin/hugo
$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2026-03-17T19:51:14Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3+esm2

hugo gen chromastyles only earns its place when your configuration leaves markup.highlight.noClasses disabled. In that mode Hugo emits classes such as chroma and expects a matching stylesheet. If you use inline styles instead, skip this guide; there is nothing to generate.

Check the setting from the site root. The exact command depends on your configuration format, so inspect it without editing anything:

$ rg -n 'noClasses|highlight' hugo.yaml config/ 2>/dev/null
config/_default/markup.yaml:4:  noClasses: false

Your path and output may differ. If the search turns up noClasses: true, stop here unless you are deliberately changing the highlighting design; this command does not alter the site configuration by itself.

2. Choose a style and generate a temporary file

This installed version defaults to the friendly style. Name the style explicitly in scripts so a future default change cannot silently rewrite your generated CSS. Hugo writes the stylesheet to standard output, so redirect it into a temporary file inside the site or a private scratch directory.

$ tmp_css=$(mktemp /tmp/hugo-chroma.XXXXXX.css)
$ hugo gen chromastyles --style monokai > "$tmp_css"
$ printf 'exit status: %s\n' "$?"
exit status: 0

--style takes a Chroma style name; the official Hugo style gallery is the practical place to pick one. Common names include friendly, monokai, github and dracula, but check the gallery or your installed command before wiring a name into automation.

Checkpoint

Make sure the command produced CSS rather than an empty file or an error message:

$ wc -c "$tmp_css"
4537 /tmp/hugo-chroma.A1b2C3.css
$ sed -n '1,4p' "$tmp_css"
/* Background */ .bg { color: #f8f8f2; background-color: #272822; }
/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; }
/* Other */ .chroma .x {  }
/* Error */ .chroma .err { color: #f92672 }

The byte count and colours depend on the style you chose. What actually matters is a zero exit status, a non-zero file size, and selectors that start with Chroma's classes.

3. Add line highlighting or line-number colours only when needed

--highlightStyle and --linesStyle do not pick another named theme. They take Chroma style elements for highlighted lines and line numbers. This example adds a pale background to highlighted lines and a grey foreground to line numbers:

$ hugo gen chromastyles \
    --style monokai \
    --highlightStyle 'bg:#ffeeaa' \
    --linesStyle '#888888' \
    > "$tmp_css"
$ rg -n 'LineHighlight|LineNumbers' "$tmp_css"
9:/* LineHighlight */ .chroma .hl { background-color: #ffeeaa }
11:/* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #888888 }

Keep these separate from --style in your head as well as your command line. Passing a theme name like monokai to --highlightStyle is a different operation and can fail with an unknown style element error. Skip both options entirely if you do not need special line treatment.

4. Check the output before changing the site

Inspect the selectors and look for an error string before you install anything:

$ test -s "$tmp_css" && echo 'stylesheet is non-empty'
stylesheet is non-empty
$ rg -n '(^| )\.chroma|LineHighlight|LineNumbers' "$tmp_css" | head
1:/* Background */ .bg { color: #f8f8f2; background-color: #272822; }
2:/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; }
9:/* LineHighlight */ .chroma .hl { background-color: #ffeeaa }

Do not install a file if the exit status was non-zero. A failed command can still leave a partial file behind when shell redirection is in play, so keep the old asset until the replacement has passed these checks.

5. Install atomically without overwriting a working asset

Swap in your real site directory for the placeholder paths below. This changes site state, but does not need sudo when you own the Hugo project:

$ site_css='static/css/syntax.css'
$ install -D -m 0644 "$tmp_css" "$site_css.new"
$ if [ -e "$site_css" ] && [ ! -e "$site_css.bak" ]; then cp --preserve=all "$site_css" "$site_css.bak"; fi
$ mv "$site_css.new" "$site_css"
$ rm -f "$tmp_css"
$ test -s "$site_css" && echo "installed: $site_css"
installed: static/css/syntax.css

The backup step may report nothing if the asset never existed. The mv only happens after the new file is written safely. If the new CSS causes a problem, restore with mv "$site_css.bak" "$site_css", but only after you have confirmed the backup exists and checked its path.

Warning

Do not delete the backup as part of a blind deployment. Once you have rendered and checked the site, remove it deliberately with rm -- "$site_css.bak" if you no longer need recovery; that deletion is irreversible.

6. Build the site and diagnose failures

Run Hugo from the site root and confirm the generated pages still carry the expected Chroma classes:

$ hugo --quiet
$ rg -n 'class="[^"]*chroma|class="chroma' public/ | head
public/posts/example/index.html:42:<div class="highlight"><div style="color:#f8f8f2;background-color:#272822" class="chroma">

The exact HTML varies with the template and the highlighting options in play. If the style name is rejected, check the installed help and the official style gallery for a supported one. If the CSS exists but code still looks unstyled, confirm the stylesheet is actually loaded by the final page and that its selectors match the classes Hugo is emitting; a successful generation proves nothing about whether your template loads the file.

To undo this whole guide, restore "$site_css.bak" as described above and rebuild. Nothing here needs elevated privileges or a service restart.

Done means

  • Checked the setup. Hugo's version and the site's noClasses setting were confirmed first.
  • Generated a valid stylesheet. A named Chroma style produced a non-empty CSS file with exit status 0.
  • Kept line options separate. Any line highlighting or numbering used style elements, not theme names.
  • Protected the old asset. The existing stylesheet stayed in place until the replacement passed review.
  • Confirmed it renders. A Hugo build completed and its output carries the classes the stylesheet targets.