Hugo Tutorial: Building a Blog From Scratch in 30 Minutes

Hugo tutorial: a step-by-step guide to building a blog from scratch. Installing Hugo, picking a theme, configuration, deployment. A complete beginner's guide in 30 minutes.
When I decided to start a blog, the first thing I did was look at website builders. Craftum, Tilda, Wix — they all look nice, but for a developer’s blog that’s like using a microscope to hammer in nails. Then I tried WordPress and nearly went gray from the sheer number of plugins and vulnerabilities. In the end I found Hugo, and it was the best decision I made.
In this tutorial I’ll show you how to build a blog on Hugo from scratch in 30 minutes. No fluff, just practice.
Why Hugo Instead of WordPress or a Website Builder
Before installing anything, let’s figure out why Hugo specifically.
Build speed — Hugo builds sites faster than anything else. Seriously, thousands of pages in seconds. Jekyll, Gatsby, Next.js aren’t even close.
No database — all your content lives in Markdown files. No MySQL, no SQL injection vulnerabilities, no database backups. Everything lives in Git.
Markdown — you write posts in your favorite editor (Obsidian, VS Code, even vim). No browser-based WYSIWYG editors.
Hosting is nearly free — a static site can be hosted on GitHub Pages, Netlify, or Vercel. Free and fast.
Full control — want to change something in the theme? Just edit the files. No “only available in the Pro version.”
By the way, I wrote in detail about why I moved from a website builder to Hugo in Hugo vs Craftum . That post covers the pain of using website builders for a blog.
Installing Hugo
macOS
# Via Homebrew (recommended)
brew install hugo
# Verify
hugo version
Linux (Ubuntu/Debian)
# Snap — the simplest way
sudo snap install hugo --channel=extended
# Or via apt (may be an older version)
sudo apt install hugo
# Verify
hugo version
Windows
# Via Chocolatey
choco install hugo-extended
# Or via Scoop
scoop install hugo-extended
# Verify
hugo version
Important: install hugo-extended specifically, not just hugo. The extended version supports SCSS and other features that most themes need.
Creating a New Site
# Create the project
hugo new site my-blog
# Move into the folder
cd my-blog
# Initialize Git (required for themes)
git init
Project structure:
my-blog/
├── archetypes/ # Templates for new posts
├── assets/ # SCSS, JS (processed by Hugo)
├── content/ # Your content (posts, pages)
├── data/ # Data in JSON/YAML/TOML
├── i18n/ # Translations
├── layouts/ # Custom templates
├── static/ # Static files (images, CSS, JS)
├── themes/ # Themes
└── hugo.toml # Main config
Choosing and Installing a Theme
Themes account for 90% of how your blog looks. Head over to themes.gohugo.io and pick one.
My recommendations for a developer blog:
- PaperMod — minimalist, fast, popular
- Congo — modern, with a dark theme
- Blowfish — good-looking, lots of settings
- Nightfall — what I use myself
Install the theme as a git submodule:
# PaperMod
git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
# Or Congo
git submodule add https://github.com/jpanther/congo.git themes/congo
# Or Nightfall (my theme)
git submodule add https://github.com/LordMathis/hugo-theme-nightfall.git themes/nightfall
Configuring the Site
Open hugo.toml and configure it:
baseURL = 'https://yourdomain.com/'
languageCode = 'en'
title = 'My Blog'
theme = 'PaperMod' # Theme folder name
[params]
author = "Your name"
description = "A blog about programming and technology"
# For PaperMod
showReadingTime = true
showShareButtons = true
showPostNavLinks = true
[menu]
[[menu.main]]
name = "Blog"
url = "/posts/"
weight = 1
[[menu.main]]
name = "About"
url = "/about/"
weight = 2
# SEO
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true # Allows HTML in Markdown
Every theme has its own set of parameters — check the theme’s documentation.
Writing Your First Post
# Create a post
hugo new posts/my-first-post/index.md
Hugo will create a file with basic frontmatter. Let’s edit it:
---
title: "My First Post"
date: 2025-01-31
description: "SEO description of the post, 150-160 characters"
tags:
- hugo
- blog
---
Hello, world! This is my first Hugo post.
## Second-Level Heading
Post body text. Full **Markdown** is supported:
- lists
- *italics*
- `code`
### Syntax-Highlighted Code
```go
package main
import "fmt"
func main() {
fmt.Println("Hello, Hugo!")
}
Images
Put an image in the post’s folder and insert it:

### Post Structure (Page Bundles)
Hugo supports two ways of organizing posts:
**1. Standalone files:**
content/posts/ ├── my-first-post.md ├── second-post.md
**2. Page Bundles (recommended):**
content/posts/ ├── my-first-post/ │ ├── index.md │ └── image.webp ├── second-post/ │ ├── index.md │ └── screenshot.png
Page Bundles are more convenient — images live right next to the post instead of in a shared `static/` folder.
## Local Server
```bash
# Start the development server
hugo server -D
# -D shows drafts (draft: true)
Open http://localhost:1313 and you’ll see your blog. The server automatically reloads the page whenever you make changes — very convenient.
Building for Production
# Build the site
hugo
# Or with minification
hugo --minify
The finished site will show up in the public/ folder. These are static HTML/CSS/JS files that you can host anywhere.
Deploying to GitHub Pages
The easiest way to host a blog for free.
1. Create a Repository
Create a repository named username.github.io on GitHub.
2. Push Your Code
git add .
git commit -m "Initial commit"
git remote add origin git@github.com:username/username.github.io.git
git push -u origin main
3. Set Up GitHub Actions
Create .github/workflows/hugo.yml:
name: Deploy Hugo site
on:
push:
branches: [main]
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true # For themes added as submodules
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
4. Enable Pages
In the repository settings: Settings → Pages → Source: gh-pages branch.
A couple of minutes later your blog will be live at https://username.github.io.
Deploying to Your Own Server
If you want full control, deploy to a VPS. I use GitLab CI/CD:
# .gitlab-ci.yml
stages:
- build
- deploy
build:
stage: build
image: registry.gitlab.com/pages/hugo:latest
script:
- hugo --minify
artifacts:
paths:
- public
deploy:
stage: deploy
script:
- rsync -avz public/ user@server:/var/www/blog/
only:
- main
I wrote more about automation and CI/CD for developers in my post about Cursor AI — that one covers automating the routine stuff.
Useful Hugo Commands
# Create a new post
hugo new posts/article-name/index.md
# Local server with drafts
hugo server -D
# Build
hugo --minify
# Build including future posts
hugo --minify --buildFuture
# List all posts
hugo list all
# Check the config
hugo config
SEO Optimization
Out of the box, Hugo generates:
sitemap.xml— a sitemap- an RSS feed
- a proper URL structure
For full SEO optimization, add to your templates:
- Open Graph tags
- Twitter Cards
- Schema.org markup
- Canonical URLs
If you’re curious how I optimized this blog for SEO, let me know and I might write a separate post about it.
Common Problems
The Theme Isn’t Applied
# Check that the theme is specified in the config
cat hugo.toml | grep theme
# Check that the theme folder exists
ls themes/
Images Aren’t Showing Up
Use Page Bundles and relative paths:
 # If the image is in the post's folder
The Server Isn’t Picking Up Changes
# Restart the server
hugo server -D --disableFastRender
“TOCSS: failed to transform” Error
You need the extended version of Hugo:
hugo version # Should say "extended"
Conclusion
Hugo is a tool for people who want to control their own blog. No dependency on website builders, no monthly payments, no lag.
What to do next:
- Install Hugo and create your first post
- Pick a theme that fits your style
- Set up deployment via GitHub Actions or GitLab CI
- Write content and don’t sweat the technical details
If you want to learn about productivity when writing posts, check out time management techniques for developers .
Have questions about Hugo? Leave a comment or reach out on Telegram — happy to help.