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

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

Read a Hugo Module Graph Before You Change Dependencies

You will finish with a repeatable, read-only check of a Hugo site's module dependencies, including how to recognise a local replacement in the output. 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. They do not need elevated privileges and do not alter 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. The command is a subcommand of hugo mod, so use hugo mod graph, not a 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 that 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 associated with that project. A project with no resolved module dependencies can produce no graph lines and still exit successfully. Treat the exit status as the first check, then inspect whether the output contains the dependencies you expected.

Checkpoint: capture the result without changing files if 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 for Bash. It avoids reporting success merely because tee wrote its copy successfully. The temporary file is disposable; nothing in the Hugo project is modified by this command.

3. Read an ordinary dependency edge

Each non-empty line represents a directed relationship from one module to another. For example, a line shaped like this:

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

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

Do not infer that every module shown is enabled in the rendered site. The graph is a dependency view, while whether an import is used, disabled or selected through configuration 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. Hugo keeps that information visible in the graph. For a small local test project, the output can look like:

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

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

Use the graph to find the edge, then inspect the project's go.mod and Hugo configuration to understand why it exists. This command does not edit either file. If the replacement is accidental, remove or correct it in version control using the project's normal review process. Do not delete a dependency directory merely because it appears 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 check: the manual warns that the graph shows the version listed for a vendored module, not necessarily the version recorded in go.mod. Compare the output with the checked-in vendor contents and the module files before diagnosing a version mismatch.

Useful read-only checks are:

$ 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 source of 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 whose content and theme directories are non-standard, 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 these options into automation, because paths and glob patterns are project-specific.

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 make the next run download modules again and can remove useful evidence while you investigate. Do not add it to a routine inspection unless clearing the cache is the deliberate recovery step.

7. Diagnose a failed graph

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

If a local replacement path is 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 establish which source the build is intended to use. No elevated privilege is normally needed for these checks. Avoid sudo hugo: it can leave root-owned cache or generated files behind and does not 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 instead of treating the output as a flat package list.
  • Any => path was checked for local, machine-specific replacement behaviour.
  • Vendored versions were compared with both the graph and the project's module files.
  • No project files, services or permissions were changed during the inspection.