The Problem with Running a Dynamic Blog
If you’ve ever maintained a WordPress site, you know the routine: plugin updates, database backups, PHP version mismatches, and the occasional 500 error at 2am. For a personal tech blog or documentation site, this overhead is simply not worth it.
Static site generators fix this. No database, no server-side scripting, no moving parts at runtime. You write in Markdown, run a build command, and push plain HTML files to a CDN. Pages load instantly, hosting is often free, and there’s almost nothing to break.
I moved to a static generator three years ago and haven’t touched a PHP config or run a database backup since. Maintenance time dropped from roughly an hour a week to near zero. If your goal is writing, not server babysitting, this is the right call.
Two tools dominate this space: Hugo (Go-based, blazing fast) and Jekyll (Ruby-based, tightly integrated with GitHub Pages). They’re both solid choices. The decision usually comes down to your local toolchain and where you plan to deploy.
Core Concepts You Need to Understand First
How Static Site Generators Work
A static site generator reads your content (Markdown files), applies templates (HTML/CSS layouts), and outputs a directory of static files ready to serve. That output folder is your entire website — no database queries, no PHP execution.
The key components are:
- Content files — Markdown (
.md) files with front matter (YAML/TOML metadata at the top) - Themes/layouts — HTML templates that define how pages look
- Config file — Site-wide settings like title, base URL, and theme
- Build output — The final
public/or_site/directory you deploy
Hugo vs Jekyll: The Key Differences
Hugo is written in Go and is genuinely fast — a site with 1,000 posts typically builds in under a second. Jekyll is written in Ruby and noticeably slower at scale, but it’s the native tool for GitHub Pages. Push to a branch and GitHub builds and deploys automatically, no CI config required.
Pick Hugo if:
- You want fast build times and don’t want to manage Ruby environments
- You’re deploying to Netlify, Cloudflare Pages, or a VPS
- You prefer TOML config syntax
Pick Jekyll if:
- You’re hosting on GitHub Pages and want zero build configuration
- You’re comfortable with Ruby and the gem ecosystem
- You need a simpler, more established plugin ecosystem
Hands-On: Building Your Static Blog
Option A — Getting Started with Hugo
Install Hugo with your package manager:
# macOS
brew install hugo
# Ubuntu/Debian
sudo apt install hugo
# Verify
hugo version
Create a new site and add a theme:
hugo new site myblog
cd myblog
# Add a theme (PaperMod is clean and popular)
git init
git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod
# Set the theme in config
echo 'theme = "PaperMod"' >> hugo.toml
Create your first post:
hugo new posts/my-first-post.md
This generates a file at content/posts/my-first-post.md with front matter already filled in:
---
title: "My First Post"
date: 2024-01-15T10:00:00+09:00
draft: true
tags: ["hugo", "blog"]
---
Your content here...
Change draft: true to draft: false when you’re ready to publish. Then start the local server:
hugo server -D # -D includes draft posts during development
Open http://localhost:1313 — Hugo hot-reloads as you edit files. When you’re ready for production:
hugo
# Output is in ./public/ — deploy this directory
Option B — Getting Started with Jekyll
Jekyll needs Ruby. On Ubuntu:
sudo apt install ruby-full build-essential
gem install jekyll bundler
jekyll new myblog
cd myblog
bundle exec jekyll serve
Your site is at http://localhost:4000. Post files go in the _posts/ directory and must follow this naming convention:
# File must be named: YYYY-MM-DD-title.md
touch _posts/2024-01-15-my-first-post.md
---
layout: post
title: "My First Post"
date: 2024-01-15
categories: [programming, linux]
tags: [jekyll, blog]
---
Content starts here.
Build for production:
bundle exec jekyll build
# Output is in ./_site/
Deploying for Free
For Hugo, Cloudflare Pages is my go-to. The free tier covers 500 builds per month with unlimited bandwidth and a global CDN — more than enough for a personal blog. Setup takes about five minutes:
- Push your Hugo project to a GitHub or GitLab repo
- Connect it to Cloudflare Pages
- Set the build command to
hugoand output directory topublic - Every push to
maintriggers a new deploy automatically
For Jekyll on GitHub Pages, it’s even simpler:
# In your repo Settings > Pages
# Set source branch to main, folder to / (root)
# GitHub builds and deploys automatically
Your blog will be live at https://yourusername.github.io/repo-name within a minute or two.
Tips That Actually Save Time
A few things I wish I’d known when starting out:
- Use archetypes (Hugo) or defaults (Jekyll) to pre-fill front matter templates. You’ll add tags, categories, and SEO fields to every post — put them in your archetype once so you never forget them later.
- Keep local and production configs separate. Hugo’s environment config system lets you override settings per environment. Store your production
baseURLinconfig/production/hugo.tomland your local URL inconfig/development/hugo.toml. Runhugo --environment productionto activate the right one. - Don’t over-theme it. Pick a minimal, well-maintained theme and tweak the CSS. Heavily customized themes become maintenance headaches when upstream updates break your overrides.
- Use
draft: truefor posts in progress. Never commit a half-written article directly to your main content directory. - Add a
.gitignorethat excludes build output. Deploy from CI — don’t commit thepublic/or_site/folder into git.
# Hugo .gitignore
public/
resources/_gen/
.hugo_build.lock
# Jekyll .gitignore
_site/
.sass-cache/
.jekyll-cache/
Wrapping Up
Static blogs aren’t a niche thing anymore. For developers running personal or professional sites, they’re often the obvious choice — faster, cheaper, and far less work to maintain than a CMS.
Hugo and Jekyll both do the job well. Hugo wins on build speed and deployment flexibility. Jekyll wins on GitHub Pages integration. Start with whichever fits your existing setup. Already on GitHub and want zero CI config? Jekyll is the easier on-ramp. Deploying to Cloudflare or Netlify? Go with Hugo.
Just pick one and ship something. Migrating between static generators later is a one-afternoon job — everything is plain Markdown files, and the front matter syntax barely differs between tools.

