Hugo — API Surface#

API types#

Hugo exposes four distinct API surfaces:

  1. CLI — the primary user-facing interface
  2. HTTP dev server — a local static file server (hugo server) with dev-only endpoints
  3. Template Function API — Go template functions available to theme/site authors
  4. Library (limited) — packages consumed by other Hugo tools or tests; not a stable public library

There is no REST API, no gRPC, and no formal plugin system at runtime.


CLI#

Framework#

github.com/bep/simplecobra — a thin wrapper around github.com/spf13/cobra that enforces an interface-based command pattern (simplecobra.Commander) instead of cobra’s struct-literal approach. Every command implements Name(), Init(), Run(), PreRun(), and Commands().

Command structure#

hugo                        ← root command (also invokes build via hugoBuildCommand alias)
  build                     ← explicit alias for root build behavior
  server (serve)            ← embedded dev web server with live reload
    trust                   ← install/uninstall local TLS CA cert
  version                   ← print Hugo version + build info
  env                       ← print Hugo environment (OS, Go version, build tags)
  config                    ← print resolved site configuration
    mounts                  ← print configured module mounts
  new                       ← scaffold new items
    content                 ← create a new content file from archetype
    project                 ← create a new Hugo project skeleton
    theme                   ← create a new Hugo theme skeleton
  convert                   ← convert front matter format (toYAML, toJSON, toTOML)
  import                    ← import from other SSGs
    jekyll                  ← import a Jekyll site
  list                      ← list content pages
    all                     ← all pages
    drafts                  ← draft pages
    future                  ← pages with future publish dates
    expired                 ← expired pages
    published               ← published pages
  mod                       ← Hugo Modules management
    init                    ← initialize a new module
    verify                  ← verify module checksums
    graph                   ← print module dependency graph
    clean                   ← delete module cache
    tidy                    ← remove unused module entries
    vendor                  ← vendor module dependencies to _vendor/
    get                     ← resolve/update a module dependency
    npm
      pack                  ← pack npm dependencies from modules
  gen                       ← internal code/doc generation
    chromastyles            ← generate CSS for a Chroma syntax highlight theme
    man                     ← generate man pages
    doc                     ← generate CLI reference docs
    docshelper              ← generate internal docs helper JSON
  deploy                    ← deploy public/ to cloud storage
  release                   ← internal release helper (maintainers only)

Global (persistent) flags#

FlagDefaultPurpose
--source, -scwdfilesystem path to read files from
--destination, -dpublic/filesystem path to write output to
--environment, -eproductionbuild environment (selects config dir)
--configautoexplicit config file path
--configDirconfigconfig directory
--themesDiroverride themes directory
--logLevelwarndebug|info|warn|error
--quietfalsesuppress non-essential output
--renderToMemory, -Mfalserender to memory instead of disk
--noBuildLockfalseskip .hugo_build.lock
--clockfreeze Hugo’s clock (for reproducible builds)
--ignoreVendorPathsglob to bypass _vendor for matched modules

Build-specific flags (on hugo and hugo server)#

FlagPurpose
--theme, -tthemes to activate
--baseURL, -boverride base URL
--buildDrafts, -Dinclude drafts
--buildFuture, -Finclude future-dated content
--buildExpired, -Einclude expired content
--minifyminify output (HTML, XML, JS, CSS, SVG, JSON)
--disableKindsskip generating page kinds (home, section, taxonomy, etc.)
--enableGitInfoadd Git metadata to pages
--gcgarbage-collect unused cache files
--templateMetricsprint per-template execution timing
--renderSegmentsrender only named segments
--cleanDestinationDirremove stale files from public/
--ignoreCachebypass file cache
--polluse polling instead of fsnotify (e.g. --poll 700ms)

HTTP Dev Server (hugo server)#

The dev server is not a general-purpose HTTP server. It is a purpose-built static file server with dev-only features. Not intended for production use.

Server-specific flags#

FlagDefaultPurpose
--port, -p1313listen port
--bind127.0.0.1network interface
--liveReloadPort-1 (auto)livereload WebSocket port
--tlsAutofalseauto-generate locally-trusted TLS cert
--tlsCertFile / --tlsKeyFilemanual TLS cert
--watch, -wtruewatch for changes
--disableLiveReloadfalsewatch without browser refresh
--disableFastRenderfalsefull rebuild on every change
--renderStaticToDiskfalseserve static from disk, dynamic from memory
--noHTTPCachefalseadd Cache-Control: no-store headers
--navigateToChanged, -Nfalseauto-navigate browser to changed page
--openBrowser, -Ofalseopen browser on startup
--pproffalseenable pprof server on :8080

Route table#

{baseURL}/                  → static file server over public/ (http.FileServer)
{baseURL}/livereload.js     → embedded livereload client script
{baseURL}/livereload        → WebSocket upgrade endpoint (livereload protocol)
/__stop                     → test-mode shutdown endpoint (not exposed in normal use)

Middleware chain (applied to all static requests)#

  1. Error display — if build error present, render error page with injected livereload
  2. Cache headers — inject no-store if --noHTTPCache
  3. Custom server headers — match request URI against server.headers config rules
  4. Redirect rules — match against server.redirects config; handles 301/302/404/200-rewrite
  5. Fast render — on navigation request to unvisited URL, trigger partial re-render before serving
  6. Static file handlerhttp.FileServer over afero-backed public directory
  7. Livereload injection — response transformer injects <script> tag into HTML responses (transform/livereloadinject)

Custom response header#

X-Hugo-Redirect: true is set on responses that were redirected via Hugo’s redirect rules (mirrors Netlify behavior).


Template Function API#

This is the largest and most important API surface for Hugo users. Theme and site authors call these functions from Go text/template / html/template templates. Each namespace is a struct registered as a global template variable (e.g. {{ collections.Where . "Section" "blog" }}).

Hugo exposes ~30 namespaces. Most functions are also available as top-level aliases without the namespace prefix.

Namespace summary#

NamespaceApprox. functionsKey purpose
collections~138slice/map operations: Where, Group, Sort, Shuffle, Uniq, Apply, Append, Merge, After, First, Last, Index, In, Intersect, Reverse, Seq, Dictionary, Slice
strings~64string manipulation: HasPrefix, TrimPrefix, Replace, Split, Upper, Lower, Truncate, Title, Chomp, RuneCount
math~61arithmetic, log, floor, ceil, sqrt, min, max, mod, rand
compare~39eq, ne, lt, gt, ge, le, default, cond
resources~21asset pipeline: Get, GetRemote, Match, ByType, Concat, FromString, ExecuteAsTemplate, Fingerprint, Minify, PostProcess, Copy
urls~20AbsURL, RelURL, URLize, Anchorize, AbsLangURL, RelLangURL
partials~20Include, IncludeCached, Return
path~17Join, Dir, Base, Ext, Split, Clean
css~17Sass/SCSS: Sass (Dart Sass), PostCSS
time~14Now, Format, Since, Until, ParseDuration, AsTime
safe~14type-safe HTML/JS/CSS/URL trust markers: HTML, JS, CSS, URL, HTMLAttr
fmt~14Errorf, Printf, Println, Sprint, Sprintf
reflect~13IsMap, IsSlice, IsString, IsFloat, IsInt, IsBool
lang~13Translate (i18n), FormatNumber, FormatCurrency, FormatAccounting, FormatPercent
images~13Filter, Process, Config, image filters (Brightness, Contrast, Grayscale, Pixelate, Blur, etc.)
debug~12Dump, Timer — development aids
cast~11ToInt, ToString, ToFloat, ToBool, ToTime, ToSlice
crypto~10MD5, SHA1, SHA256, FNV32a, HMAC
encoding~8Base64Encode/Decode, Jsonify, Unmarshal (TOML/YAML/JSON/CSV)
inflect~6Humanize, Pluralize, Singularize
jsesbuild: Build, Babel
hugoHugo version, environment, .IsProduction, .IsServer, BuildDate
pagepage-level helpers
sitesite-level helpers
hashFNV32a, XxHash
diagramsGoat (ASCII art diagrams)
openapiload and query OpenAPI specs
transformHighlight, MarkdownTo, Remarshal, ToMath (KaTeX)
templatesExists, DoDefer

Page object API (template dot .)#

The page.Page interface is the central object available as . in page templates. It is composed from ~20 embedded provider interfaces:

ProviderKey methods
ContentProvider.Content, .Plain, .PlainWords, .Summary, .Truncated, .WordCount, .ReadingTime, .FuzzyWordCount
PageMetaProvider.Title, .Date, .PublishDate, .ExpiryDate, .Params, .Weight, .Description, .Keywords, .Aliases, .Slug, .URL, .Draft, .Kind, .Type, .Section, .Lang
ChildCareProvider.Pages, .RegularPages, .RegularPagesRecursive, .Sections
TreeProvider.Parent, .Ancestors, .FirstSection, .IsAncestor, .IsDescendant, .InSection
OutputFormatsProvider.OutputFormats, .AlternativeOutputFormats
TranslationsProvider.Translations, .AllTranslations, .IsTranslated
FileProvider.File (path, filename, basename, dir, extension, logical name)
GitInfoProvider.GitInfo (hash, date, author, CODEOWNERS)
RefProvider.Ref, .RelRef
TableOfContentsProvider.TableOfContents
RelatedKeywordsProviderfor .Site.RegularPages.Related
ShortcodeInfoProvider.HasShortcode
SitesProvider.Site, .Sites
GetPageProvider.GetPage

Plugin / Extension System#

Hugo has no runtime plugin system. All extensibility is compile-time or configuration-driven:

Markup converters (markup/converter)#

The only true runtime extension point. A converter.Provider registers a named converter identified by a string (e.g. "goldmark", "asciidocext", "pandoc", "rst", "org").

  • Interface: converter.Provider + converter.ProviderProvider
  • Registration: markup.NewConverterProvider(cfg, providers...) — called at Deps init
  • Built-in providers: goldmark (default), asciidocext (calls asciidoctor binary), pandoc (calls pandoc binary), rst (calls rst2html binary), org-mode
  • External converters must be compiled in — no dynamic loading

Hugo Modules (composition, not code extension)#

Hugo’s module system (mirrors Go modules) lets users compose themes, content, and assets from multiple sources. Not a code plugin system; modules can only contribute file system content (layouts, content, assets, i18n, static, data).

Build-tag editions#

Three compile-time editions control optional features:

  • none: pure Go, no CGO
  • extended: adds Dart Sass (via WASM/warpc) and image processing (libwebp via CGO or WASM)
  • withdeploy: adds cloud deploy drivers (AWS S3, GCS, Azure Blob)

Library API (limited / internal use)#

Hugo does not position itself as a Go library for external consumers. The module path is github.com/gohugoio/hugo and there is no stable public API contract. However, several packages are usable by tools:

  • github.com/gohugoio/hugo/hugolib — core build API (NewHugoSites, Build); used by hugo itself and some third-party IDE integrations
  • github.com/gohugoio/hugo/config/allconfig — config loading
  • github.com/gohugoio/hugo/common/hugo — version info
  • github.com/gohugoio/hugo/resources/pagepage.Page interface (useful for testing)

No versioning strategy is visible for library consumers. Breaking changes happen freely between Hugo releases. The idiomatic way to embed Hugo is to pin to a specific tag and accept churn.


API design observations#

  1. CLI-first design. All user-facing functionality is CLI. The template API is a secondary surface. There is no admin API, no REST endpoint, no programmatic trigger for builds — the intended integration point is shell scripting around hugo invocations.

  2. Template API surface is enormous. ~30 namespaces with hundreds of functions make the template API the richest part of the surface. The namespace approach (collections.Where vs where) gives discoverability but also creates naming redundancy.

  3. simplecobra over raw cobra is an architectural preference: each command is a named type implementing an interface, not an anonymous struct literal. This improves testability and discoverability but adds boilerplate. The pattern is unique to Hugo in the Go ecosystem.

  4. Dev server is intentionally limited. The HTTP server does no content negotiation, no authentication, no dynamic routing beyond redirects defined in config. This is deliberate: Hugo’s output is always static files; the dev server exists only to preview them.

  5. No gRPC, no proto files. The internal WASM RPC (internal/warpc) uses a custom stdin/stdout message protocol — not gRPC — specifically to avoid CGO and network overhead. This is invisible to users.