Build Hugo's Module npm Package Safely with hugo mod npm pack
Hugo's hugo mod npm group contains helpers for projects that use Node packages through Hugo modules. On the installed machine, Hugo is version 0.123.7, and its useful subcommand is the experimental pack command. It collects dependency declarations from the project and its module tree, then writes a project-level package.json.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide takes about 10 minutes if the site already has a module configuration. You will finish with a generated package manifest that you can inspect before handing it to npm. The examples use an isolated copy of a site configuration, so replace the example paths with your actual project path.
Before you start
- Use Hugo 0.123.7 or check your own version first.
- Work from the Hugo project root, where the site's configuration and module files are available.
- Make a clean or saved copy of
package.json. The command changes files in the project.
hugo version
pwd
ls -la hugo.yaml hugo.toml hugo.json go.mod package.json package.hugo.json 2>/dev/null
The last command may report that some files do not exist. That is only an inventory check. A Hugo site does not need every listed file. The local command reports version 0.123.7, built for Linux amd64 in March 2026.
Checkpoint: understand what pack changes
In this installed release, the first run creates package.hugo.json in the project root when it is absent. Hugo uses that file as the base dependency set, then merges matching package.hugo.json files found in the dependency tree. The resulting dependencies are written to package.json, with comment metadata describing their source.
This is a file-generation step, not an npm installation step. It does not download packages or create node_modules. Do not confuse it with npm install; the latter resolves and fetches packages after you have reviewed the generated manifest.
The command is marked experimental in the installed manual. Its file layout has changed in later Hugo releases: current upstream documentation describes an auto-generated workspace under packages/hugoautogen. If your Hugo version is newer than 0.123.7, read its matching help output before relying on the older root-level result shown here.
Run the helper from the project root
- Change to the site directory you intend to update.
- Run the pack subcommand without elevated privileges.
cd /path/to/your/hugo-site
hugo mod npm pack
There is normally no success message. A silent exit with status zero is expected. Check the status and list the files that may have changed:
test "$?" -eq 0 && echo "hugo mod npm pack completed"
git status --short -- package.json package.hugo.json
Do not use sudo. The command needs to write project files and may need Hugo's module cache, both of which should belong to your normal account. If a project is owned by another account, fix ownership deliberately or run the operation as that account rather than creating root-owned output.
Inspect the generated manifest
- Review the complete diff before installing anything.
- Check that dependency names and version ranges match the modules you intended to use.
git diff -- package.json package.hugo.json
python3 -m json.tool package.json >/dev/null && echo "package.json is valid JSON"
For a small test project containing a base package.hugo.json with example-package at ^1.2.3, Hugo 0.123.7 produced a package.json with the same dependency and a comments.dependencies entry identifying it as coming from the project. Real module trees add their own declarations, and the closest declaration takes precedence when versions conflict.
Pay attention to unexpected packages, broad version ranges and changes to an existing manifest. A module update can legitimately introduce a new build dependency, but that is still a supply-chain change worth reviewing. Treat a package name you do not recognise as a reason to stop and inspect the imported modules, not as a prompt to install immediately.
Install only after review
When the diff is expected, use your project's normal npm workflow. This is the point where network access and lockfile changes may occur:
npm install
Watch the output for registry, peer-dependency or audit errors. Hugo's helper does not resolve those problems. After installation, build the site and confirm that the asset pipeline can find its imports:
hugo --minify
git status --short
The build command is safe in the usual sense, but it may write generated output if your site configuration requests it. Confirm its destination before using a production build or deployment wrapper.
Recover from an unwanted change
Do not delete a generated file blindly if it contains a dependency declaration you still need. First save any intentional edits, then use version control to restore only the files changed by this operation:
git diff -- package.json package.hugo.json
git restore -- package.json package.hugo.json
git restore is destructive to uncommitted changes in those two files. If you have edited either file since running Hugo, copy those edits elsewhere first or restore individual hunks with git restore -p. If the command created an untracked package.hugo.json, remove it only after confirming that it did not contain your base dependency set:
git status --short -- package.json package.hugo.json
rm -- package.hugo.json
The final command is deliberately separate and can permanently remove an untracked file. Never run it from the wrong directory.
Done means
hugo versionwas checked and the command's version-specific output was understood.hugo mod npm packcompleted from the intended project root.- The
package.jsondiff contains only expected dependencies and metadata. npm installwas run only after that review, if packages were needed.hugo --minifycompletes and the resulting working-tree changes are understood.
For the current command reference, compare your installed help with Hugo's official hugo mod npm pack documentation and its explanation of Node.js dependencies in Hugo modules.