Hugo Build Commands Explained: `hugo`, `hugo build`, and `hugo server`

The hugo command is an alias for hugo build, both generating a static site to the public/ directory, while hugo server adds a development web server with live reload and file watching capabilities.

Hugo's command-line interface provides distinct workflows for production builds and local development. According to the gohugoio/hugo source code, the three primary commands share core build logic but differ significantly in execution context and output behavior. Understanding these differences ensures you use the right tool for deployment pipelines versus interactive development.

hugo vs hugo build: Identical Production Builds

The Default Command Alias

Running hugo without sub-commands executes the default build flow. In commands/commands.go, the newExec function wires the CLI and adds the build command as the first entry in the root command's commands slice. The Init method calls initRootCommand("build", …), which makes the default command behave exactly like the explicit hugo build sub-command.

Explicit Build Syntax

The hugo build command runs a full site build and writes output to the destination directory (default public/). It respects all build-related flags including --cleanDestinationDir, --minify, and --disableKinds. According to the source code, the hugoBuildCommand type simply forwards all lifecycle hooks to the root command (rootCmd.Run, PreRun, etc.). The actual work is performed by hugoBuilder.fullBuild and hugoBuilder.build, which invoke hugolib.Hugo.Build in commands/hugobuilder.go.

hugo server: Development Server with Live Reload

Unlike the build commands, hugo server starts an embedded development server that builds the site, serves files over HTTP, and watches the source tree for changes. Defined by newServerCommand() in commands/server.go, this command's Run method sets up a file watcher, initializes the hugoBuilder, and calls hugoBuilder.fullBuild before starting livereload.Start and the HTTP server.

The server adds development-specific capabilities:

  • File watching: Monitors source files and triggers incremental rebuilds via hugoBuilder.rebuildSites
  • Live reload: Injects live-reload scripts into pages for browser auto-refresh
  • HTTP serving: Runs a minimal http.Server (default port 1313)
  • Development flags: Supports --port, --baseURL, --watch, and --liveReload registered in commands/commandeer.go

Architectural Implementation

Both commands rely on shared infrastructure in the Hugo codebase, but diverge in their execution paths.

The CLI bootstrap begins in commands/commands.go where newExec creates a simplecobra.Exec with a rootCommand holding shared state. When no sub-command is supplied, rootCommand.Init receives the sub-command name "build" via hugoBuildCommand.Init, treating the invocation exactly like hugo build.

For server operations, hugo server creates a hugoBuilder with a serverCommand reference, starts a file-watcher via watcher.New, runs an initial full build, then serves files. The watcher triggers hugoBuilder.rebuildSites for incremental updates without restarting the entire process.

Practical Usage Examples

Production Build Commands


# Default build (writes to ./public)

hugo

# Explicit build with optimization flags

hugo build --minify --cleanDestinationDir

Development Server


# Start dev server with live reload on default port 1313

hugo server --watch --navigateToChanged

# Custom port and bind address

hugo server --port 8080 --bind 0.0.0.0

Programmatic Usage (Go)

// Build only
cmd := simplecobra.New(&rootCommand{})
cmd.Execute(context.Background(), []string{"build"})

// Start the dev server
cmd.Execute(context.Background(), []string{"server", "--port", "8080"})

Summary

  • hugo is an alias for hugo build—both execute hugoBuilder.fullBuild and output static files to the public/ directory
  • hugo build explicitly triggers production builds with support for flags like --minify and --cleanDestinationDir
  • hugo server adds file watching, live reload, and an HTTP server for interactive development
  • All commands delegate core build logic to hugobuilder.go, but only the server command initializes watcher.New and livereload.Start

Frequently Asked Questions

Is hugo exactly the same as hugo build?

Yes. According to the source code in commands/commands.go, running hugo without arguments triggers initRootCommand("build", …), making it functionally identical to the explicit sub-command. Both invoke hugoBuilder.fullBuild and write output to the public/ directory.

Can I use hugo server for production deployment?

No. While hugo server performs an initial full build, it is designed for development with overhead from file watching, live-reload script injection, and the embedded HTTP server. For production, use hugo or hugo build to generate static files and serve them with a production-grade web server like Nginx or Apache.

Does hugo server build the site differently than hugo build?

Both commands use the same core build logic via hugoBuilder.fullBuild in commands/hugobuilder.go. However, hugo server enables incremental rebuilds through hugoBuilder.rebuildSites when file changes are detected, whereas hugo build performs a complete build and exits.

Where are the build commands defined in the Hugo source code?

The CLI commands are defined across several files: commands/commands.go handles command registration and the default alias, commands/hugobuilder.go contains the shared build implementation (fullBuild, build), and commands/server.go defines the development server functionality including the file watcher and HTTP server setup.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →