Skip to content

jakejarvis/hugo-extended

 
 

Repository files navigation

Hugo via NPM

NPM Version NPM Downloads CI status

Plug-and-play binary wrapper for Hugo Extended, the awesomest static-site generator. Now with full TypeScript support and type-safe APIs!

Features

  • 🚀 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

Installation

npm install hugo-extended --save-dev
# or
yarn add hugo-extended --dev
# or
pnpm add hugo-extended --save-dev

SCSS/PostCSS Support

If you're using Hugo's SCSS features, you'll also want:

npm install postcss postcss-cli autoprefixer --save-dev

These integrate seamlessly with Hugo's built-in PostCSS pipes.

Usage

CLI Usage

The simplest way — just run hugo commands directly:

// package.json
{
  "scripts": {
    "dev": "hugo server --buildDrafts",
    "build": "hugo --minify",
    "build:preview": "hugo --baseURL \"${DEPLOY_PRIME_URL:-/}\" --buildDrafts --buildFuture"
  }
}
npm run dev

Programmatic API

Builder-style API

A 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();

Function-based API

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");

Direct Binary Access

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" });

Type Imports

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>) {
  // ...
}

API Reference

exec(command, options?)

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)
  • ReturnsPromise<void>

execWithOutput(command, options?)

Execute a Hugo command and capture output.

  • command — Hugo command string
  • options — Type-safe options object (optional)
  • ReturnsPromise<{ stdout: string; stderr: string }>

hugo (default export)

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 });

Available Commands

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

Platform Support

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)

Environment Variables

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.

Examples

# 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-extended

Troubleshooting

Hugo binary not found

If Hugo seems to disappear (rare edge case), it will be automatically reinstalled on next use. You can also manually trigger reinstallation:

npm rebuild hugo-extended

macOS installation

As 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.

License

This project is distributed under the MIT License. Hugo is distributed under the Apache License 2.0.

About

✏️ Plug-and-play Node.js wrapper for Hugo Extended, the awesomest static-site generator.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

No contributors

Languages

  • TypeScript 97.6%
  • JavaScript 2.4%