Home / Alt manpages / hugo-mod-graph(1)

  • hugo-mod-graph(1)
  • User command
  • linux

Read a Hugo Module Graph Before You Change Dependencies

hugo mod graph shows you exactly what a Hugo site depends on before you touch a single version number. It is a repeatable, read-only check, and it will flag a local replacement hiding in the output if one exists. Allow about ten minutes. You need Hugo, the site's working directory, and a shell. The examples use Hugo 0.123.7, the version installed on this machine.

1. Check the installed command

Run the version and help checks from an ordinary shell. Neither needs elevated privileges, and neither touches the project:

$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2026-03-17T19:51:14Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3+esm2
$ hugo mod graph --help
Print a module dependency graph with information about module status (disabled, vendored).

Your build date or vendor suffix may differ. This is a subcommand of hugo mod, so run hugo mod graph, not some separate hugo-mod-graph executable. The installed manual page documents the same synopsis: hugo mod graph [flags] [args].

2. Run the graph from the site directory

Change into the Hugo project you want to inspect, then run the graph command:

$ cd /path/to/your/hugo-site
$ hugo mod graph

Hugo reads the module configuration and Go module data tied to that project. A project with no resolved dependencies can print no graph lines at all and still exit successfully, so treat the exit status as the first check, then look at whether the output contains what you expected.

Checkpoint

Capture the result without touching any files, in case you need to review it later:

$ hugo mod graph | tee /tmp/hugo-module-graph.txt
$ test "${PIPESTATUS[0]}" -eq 0 && echo 'graph command succeeded'
graph command succeeded

The PIPESTATUS check is Bash-specific. It stops you reporting success merely because tee managed to write its copy. The temporary file is disposable; nothing in the Hugo project changes because of this command.

3. Read an ordinary dependency edge

Each non-empty line describes a directed relationship between two modules. A line shaped like this:

example.test/site github.com/example/[email protected]

means example.test/site depends on the module github.com/example/theme at version v1.2.3. Left-hand side is the parent, right-hand side is the dependency. A larger project usually prints several lines, so scan for the module you're about to upgrade, and for anything supplying a theme, shortcode or asset.

Do not assume every module shown is enabled in the rendered site. The graph is a dependency view; whether an import is actually used, disabled or selected depends on the project's module settings and content.

4. Recognise a local replacement

A Go replace directive can point a dependency at a directory on disk, and Hugo keeps that visible in the graph. For a small local test project, the output can look like this:

example.test/site example.test/[email protected] => /tmp/hugo-mod-graph-fixture/modules/example.test/theme

The => part is the tell: this edge resolves from a local path rather than being fetched from the module proxy at that version. Check the path before assuming another developer or build host can reproduce it. A replacement pointing at an absolute path is especially likely to be machine-specific.

Use the graph to find the edge, then check the project's go.mod and Hugo configuration to understand why it is there. This command edits neither file. If the replacement turns out to be accidental, remove or correct it through version control using the project's normal review process; do not delete a dependency directory just because it showed up in the graph.

5. Check vendored and disabled status carefully

The command reports module status information such as disabled and vendored modules. A vendored module deserves an extra look: the manual warns that the graph shows the version listed for a vendored module, which is not necessarily the version recorded in go.mod. Compare the output against the checked-in vendor contents and the module files before you diagnose a version mismatch.

Useful read-only checks:

$ test -f go.mod && sed -n '1,160p' go.mod
$ test -d _vendor && find _vendor -maxdepth 2 -type f -name go.mod -print
$ hugo mod graph

Hugo's default configuration file is hugo.yaml, hugo.json or hugo.toml. If your project keeps configuration elsewhere, pass the documented --config or --configDir option. Keep the graph command and the configuration inspection pointed at the same project; running one from a parent directory is a common way to get a surprisingly empty result.

6. Use the relevant flags without changing state

The graph command accepts several ordinary path and selection options. For a project with non-standard content and theme directories, make those paths explicit:

$ hugo mod graph \
    --contentDir /path/to/your/hugo-site/content \
    --theme custom-theme \
    --themesDir /path/to/your/hugo-site/themes

--baseURL supplies the site's hostname and path when that context matters to module processing. --cacheDir selects Hugo's cache directory. --ignoreVendorPaths ignores matching vendor paths. Read the installed help before copying any of these into automation, since paths and glob patterns are project-specific.

Warning

Be cautious with --clean. It deletes cached modules for dependencies that fail verification. That is a local cache change, not a project-file change, but it can force the next run to download modules again and can wipe out useful evidence mid-investigation. Do not add it to a routine inspection unless clearing the cache is the deliberate recovery step.

7. Diagnose a failed graph

If Hugo says it cannot download or verify a module, rerun without --clean first and keep the complete error text. Check the module path, the requested version, network access and any local replace path. A graph failure does not prove the module is missing from the configuration.

If a local replacement path has gone missing, restore the expected checkout or correct the replacement through the project's normal change process. If a vendored tree and go.mod disagree, stop before upgrading anything and work out which source the build is actually meant to use. None of these checks need elevated privilege. Avoid sudo hugo: it can leave root-owned cache or generated files behind and does nothing to repair dependency metadata.

Done means

  • hugo version identified the installed release, here Hugo 0.123.7.
  • hugo mod graph ran from the intended site directory and returned success.
  • You read the parent-to-dependency edges, not a flat package list.
  • Any => path was checked for local, machine-specific replacement behaviour.
  • Vendored versions were compared against both the graph and the project's module files.
  • Nothing changed. No project files, services or permissions were touched during the inspection.