Plug-and-play binary wrapper for Hugo Extended, the awesomest static-site generator. Now with full TypeScript support and type-safe APIs!
- 🚀 Zero configuration — Hugo binary is automatically downloaded on install
- 📦 Version-locked — Package version matches Hugo version (e.g.,
[email protected]= Hugo v0.140.0) - 🔒 Type-safe API — Full TypeScript support with autocomplete for all Hugo commands and flags
- ⚡ Multiple APIs — Use CLI, function-based, or builder-style APIs
- 🎯 Extended by default — Automatically uses Hugo Extended on supported platforms
npm install hugo-extended --save-dev
# or
yarn add hugo-extended --dev
# or
pnpm add hugo-extended --save-devIf you're using Hugo's SCSS features, you'll also want:
npm install postcss postcss-cli autoprefixer --save-devThese integrate seamlessly with Hugo's built-in PostCSS pipes.
The simplest way — just run hugo commands directly:
npm run devA fluent interface where each Hugo command is a method:
import hugo from "hugo-extended";
// Start server
await hugo.server({
port: 1313,
buildDrafts: true,
});
// Build site
await hugo.build({
minify: true,
environment: "production",
});
// Module commands
await hugo.mod.get();
await hugo.mod.tidy();
await hugo.mod.clean({ all: true });
// Generate shell completions
await hugo.completion.zsh();Use exec() for commands that output to the console, or execWithOutput() to capture the output:
import { exec, execWithOutput } from "hugo-extended";
// Start development server with full type safety
await exec("server", {
port: 1313,
buildDrafts: true,
navigateToChanged: true,
});
// Build for production
await exec("build", {
minify: true,
cleanDestinationDir: true,
baseURL: "https://example.com",
});
// Capture command output
const { stdout } = await execWithOutput("version");
console.log(stdout); // "hugo v0.140.0+extended darwin/arm64 ..."
// List all content pages
const { stdout: pages } = await execWithOutput("list all");For advanced use cases, get the Hugo binary path directly:
import hugo from "hugo-extended";
import { spawn } from "child_process";
const binPath = await hugo();
console.log(binPath); // "/usr/local/bin/hugo" or similar
// Use with spawn, exec, or any process library
spawn(binPath, ["version"], { stdio: "inherit" });Import Hugo types for use in your own code:
import type { HugoCommand, HugoOptionsFor, HugoServerOptions } from "hugo-extended";
// Type-safe option objects
const serverOpts: HugoServerOptions = {
port: 1313,
buildDrafts: true,
disableLiveReload: false,
};
// Generic helper
function runHugo<C extends HugoCommand>(cmd: C, opts: HugoOptionsFor<C>) {
// ...
}Execute a Hugo command with inherited stdio (output goes to console).
- command — Hugo command string (e.g.,
"server","build","mod clean") - options — Type-safe options object (optional)
- Returns —
Promise<void>
Execute a Hugo command and capture output.
- command — Hugo command string
- options — Type-safe options object (optional)
- Returns —
Promise<{ stdout: string; stderr: string }>
The default export is both callable (returns binary path) and has builder methods:
// Get binary path (backward compatible)
const binPath = await hugo();
// Builder methods
await hugo.build({ minify: true });
await hugo.server({ port: 3000 });All Hugo commands are fully typed with autocomplete:
| Command | Builder Method | Description |
|---|---|---|
build |
hugo.build() |
Build your site |
server |
hugo.server() |
Start dev server |
new |
hugo.new() |
Create new content |
mod get |
hugo.mod.get() |
Download modules |
mod tidy |
hugo.mod.tidy() |
Clean go.mod/go.sum |
mod clean |
hugo.mod.clean() |
Clean module cache |
mod vendor |
hugo.mod.vendor() |
Vendor dependencies |
list all |
hugo.list.all() |
List all content |
list drafts |
hugo.list.drafts() |
List draft content |
config |
hugo.config() |
Print configuration |
version |
hugo.version() |
Print version |
env |
hugo.env() |
Print environment |
| ... | ... | All Hugo commands supported |
Hugo Extended is automatically used on supported platforms:
| Platform | Architecture | Hugo Extended |
|---|---|---|
| macOS | x64, ARM64 | ✅ |
| Linux | x64, ARM64 | ✅ |
| Windows | x64 | ✅ |
| Windows | ARM64 | ❌ (vanilla Hugo) |
| FreeBSD | x64 | ❌ (vanilla Hugo) |
Customize installation and runtime behavior with these environment variables:
| Variable | Description |
|---|---|
HUGO_OVERRIDE_VERSION |
Install a specific Hugo version instead of the package version. Example: HUGO_OVERRIDE_VERSION=0.139.0 npm install |
HUGO_NO_EXTENDED |
Force vanilla Hugo instead of Extended edition. Example: HUGO_NO_EXTENDED=1 npm install |
HUGO_SKIP_DOWNLOAD |
Skip the postinstall binary download entirely. Useful for CI caching or Docker layer optimization. |
HUGO_BIN_PATH |
Use a pre-existing Hugo binary instead of the bundled one. Example: HUGO_BIN_PATH=/usr/local/bin/hugo |
HUGO_MIRROR_BASE_URL |
Download from a custom mirror instead of GitHub releases. Example: HUGO_MIRROR_BASE_URL=https://mirror.example.com/hugo |
HUGO_SKIP_CHECKSUM |
Skip SHA-256 checksum verification. Use with caution. |
HUGO_QUIET |
Suppress installation progress output. |
# Install a specific older version
HUGO_OVERRIDE_VERSION=0.139.0 npm install hugo-extended
# Skip download for CI caching (when binary is already cached)
HUGO_SKIP_DOWNLOAD=1 npm ci
# Use smaller vanilla Hugo (no SCSS support)
HUGO_NO_EXTENDED=1 npm install hugo-extended
# Use a corporate mirror
HUGO_MIRROR_BASE_URL=https://internal.example.com/hugo npm install hugo-extendedIf Hugo seems to disappear (rare edge case), it will be automatically reinstalled on next use. You can also manually trigger reinstallation:
npm rebuild hugo-extendedAs of v0.153.0, Hugo is distributed as a .pkg installer for macOS. This package extracts the binary locally using pkgutil --expand-full, so no sudo or global installation is required. The Hugo binary stays in node_modules just like on other platforms.
This project is distributed under the MIT License. Hugo is distributed under the Apache License 2.0.