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

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

Build Hugo's Module npm Package Safely with hugo mod npm pack

hugo mod npm pack turns the Node dependencies scattered across your Hugo modules into one readable package.json. On this machine Hugo is version 0.123.7, and pack is still the experimental one command in the hugo mod npm group worth knowing.

Give it about 10 minutes if the site already has a module configuration. You will finish with a generated manifest you can inspect before npm ever runs. The examples below use a throwaway copy of a site, so swap in your real project path.

1. Check versions and take stock

  1. Confirm your Hugo version. Use 0.123.7 or check your own first; the file layout described here is version-specific.
  2. Work from the project root. That's where the site configuration and module files live.
  3. Save a copy of package.json. The command writes to it, so keep a backup or a clean commit first.
hugo version
pwd
ls -la hugo.yaml hugo.toml hugo.json go.mod package.json package.hugo.json 2>/dev/null

Missing files from that last command are fine: a Hugo site doesn't need every one of them, it's just an inventory check. The local install reports version 0.123.7, built for Linux amd64 in March 2026.

2. Know what pack actually changes

On first run, pack creates package.hugo.json in the project root if it's absent, then uses that as the base dependency set. It merges in matching package.hugo.json files from the module tree and writes the result to package.json, with comment metadata recording where each entry came from.

This is a file-generation step, nothing more. It doesn't download packages or touch node_modules. Don't confuse it with npm install, which comes later, after you've reviewed what pack wrote.

Checkpoint

The installed manual marks this command experimental, and later Hugo releases have already changed the file layout: current upstream docs describe an auto-generated workspace under packages/hugoautogen instead. If your Hugo is newer than 0.123.7, check its own help output rather than trusting the root-level behaviour shown here. For the current reference, compare against Hugo's official hugo mod npm pack documentation and its page on Node.js dependencies in Hugo modules.

3. Run the helper from the project root

  1. Change into the site you're updating. Not a parent directory, not a sibling.
  2. Run pack without elevated privileges. It only needs to write files you already own.
cd /path/to/your/hugo-site
hugo mod npm pack

There's normally no success message. A silent exit with status zero is the expected result, not a sign something went wrong. Check the status and see what changed:

test "$?" -eq 0 && echo "hugo mod npm pack completed"
git status --short -- package.json package.hugo.json

Warning

Don't use sudo here. The command writes project files and may touch Hugo's module cache, both of which should belong to your normal account. If a project is owned by someone else, fix ownership deliberately or run as that account, rather than leaving root-owned files behind.

4. Inspect the generated manifest

  1. Read the full diff before installing anything. Don't skim it.
  2. Match dependency names and version ranges against what you intended.
git diff -- package.json package.hugo.json
python3 -m json.tool package.json >/dev/null && echo "package.json is valid JSON"

Example

For a small test project with a base package.hugo.json declaring example-package at ^1.2.3, Hugo 0.123.7 wrote a package.json with that same dependency and a comments.dependencies entry marking it as coming from the project. Real module trees add their own declarations on top, and when two disagree, the one closest to the project wins.

Watch for packages you don't recognise, version ranges that look too broad, and changes to a manifest that already existed. A module update can legitimately pull in a new build dependency, but that's still a supply-chain change worth a proper look, not a reason to install on autopilot.

5. Install only after review

Once the diff looks right, use your project's normal npm workflow. This is where network access and lockfile changes actually happen:

npm install

Watch for registry, peer-dependency or audit errors: pack doesn't resolve any of those for you. After installing, build the site and check the asset pipeline can find its imports:

hugo --minify
git status --short

The build itself is safe in the usual sense, but it may write generated output if your site configuration asks for it. Confirm the destination before running this inside a production build or deployment wrapper.

6. Recover from an unwanted change

Don't delete a generated file blindly if it still holds a dependency declaration you need. Save any intentional edits first, then let version control restore only the files this command touched:

git diff -- package.json package.hugo.json
git restore -- package.json package.hugo.json

Warning

git restore destroys uncommitted changes in those two files. If you'd edited either since running Hugo, copy those edits out first, or restore just the relevant hunks with git restore -p. If pack created an untracked package.hugo.json, remove it only after confirming it didn't hold your base dependency set:

git status --short -- package.json package.hugo.json
rm -- package.hugo.json

That last command is kept deliberately separate, and it can permanently remove an untracked file. Never run it from the wrong directory.

Done means

  • Version checked. hugo version matched what this guide expects, or you adjusted for your own.
  • Pack completed from the right root. hugo mod npm pack ran from the intended project directory.
  • Diff reviewed. The package.json change contains only expected dependencies and metadata.
  • Install came after review. npm install ran only once the manifest looked right.
  • Build confirmed. hugo --minify completes and you understand what it changed in the working tree.