Right, let’s talk about hugo mod tidy and vendor. These two commands are your best friends for keeping your Hugo project’s dependencies from turning into a digital hoarder’s paradise. They’re the dynamic duo of dependency management, and you’re about to become the commissioner.

First, hugo mod tidy. This is your cleanup crew. You know how go mod tidy prunes the unused crud from your go.mod and go.sum? This is the exact same concept, just wearing a Hugo-themed cape. When you’re experimenting with modules—adding a theme here, trying a cool shortcode module there—your go.mod file can accumulate entries for things you’re no longer using. This isn’t just messy; it can cause conflicts or pull in unnecessary code. Running hugo mod tidy sweeps through your project, looks at what you’re actually importing in your config, and then ruthlessly evicts any module requirements that aren’t needed. It’s the Marie Kondo of your Hugo project. If it doesn’t spark joy (or, more accurately, if it doesn’t resolve a config directive), it’s gone.

# Navigate to your project root and run:
hugo mod tidy

You’ll see it remove lines from your go.mod and go.sum. It’s deeply satisfying. Do this before you commit your code. Seriously. Your future self and anyone else who clones your repo will thank you for not making them download half the internet.

Now, onto hugo mod vendor. This command is a bit more divisive, and whether you use it depends on your philosophy. By default, Hugo fetches your modules on-the-fly, caching them in your system’s general Go cache (~/go/pkg/mod). This is fine, until it isn’t. Maybe you’re on a plane with spotty WiFi, your CI/CD build is timing out fetching from GitHub, or you just want the absolute guarantee that the exact same code is available forever, regardless of what some maintainer does to a Git tag.

The vendor command is your solution. It takes all your module dependencies and copies them, in their entirety, into a vendor directory at the root of your project.

# This populates the ./vendor directory with all your modules
hugo mod vendor

Why would you ever vendor?

The biggest reason is reproducibility and offline development. Once vendored, Hugo will preferentially use the code in the ./vendor directory. Your project is now self-contained. You can zip it up, send it to a colleague, and it’ll build exactly the same, no internet required. It’s also a lifesaver for CI/CD pipelines. Telling your build runner to hugo mod vendor and then hugo --ignoreVendorPaths="**" (to ignore any other vendored directories) is often infinitely more reliable than hoping every git fetch during a build goes perfectly.

The inevitable “but…”

Vendoring has a dark side: it bloats your repository. You’re going from a few lines in go.mod to potentially hundreds of megabytes of code in your vendor/ folder. This is the trade-off. If you’re using Git, you need to decide whether to commit this vendor/ directory. My rule of thumb: for a small, personal site, it’s probably overkill. For a large, critical corporate site built by a team? It’s worth the disk space for the stability. Just be ready for your git clone times to increase.

A crucial pitfall: the _vendor directory

Here’s where Hugo’s designers, in their infinite wisdom, decided to be “helpful.” If you have a directory named _vendor (with an underscore) at your project root, Hugo will use it automatically, with最高优先级 (highest priority), instead of the regular vendor or the network. This is a common source of confusion. You run hugo mod vendor, expect it to work, but your changes aren’t reflected because Hugo is silently using an old _vendor directory you forgot about.

# If things aren't working as expected, check for this sneaky folder:
ls -la | grep _vendor

My advice? Unless you have a very specific need, avoid _vendor. Use the standard hugo mod vendor which creates vendor (no underscore), and then use the --ignoreVendorPaths="**" flag when you don’t want to use the vendored code. This gives you explicit control, which is always better than implicit “magic.”

So, the workflow is simple: hugo mod tidy to keep your requirements clean, and hugo mod vendor when you need a sealed, immutable, offline-compatible snapshot of your world. Just don’t forget to check for that pesky _vendor folder if things go sideways.