A Guide to Migrating from Jekyll to Hugo
When I decided to migrate from Jekyll to Hugo, I consulted numerous documents and tutorials but still encountered quite a few unexpected difficulties. This migration wasn’t simply about changing static site generators—it involved adapting to an entirely different ecosystem and philosophy.
This post aims to provide a practical migration guide, drawing from my personal experiences, for anyone considering switching from Jekyll to Hugo. I’ve included detailed steps, commands, and key considerations to make the process smoother for you.
✅ Key Differences Before Migration
Although both Jekyll and Hugo are static site generators (SSGs), they have several fundamental differences:
Aspect | Jekyll (Ruby-based) | Hugo (Go-based) |
---|---|---|
Build Speed | Rapidly slows down as the number of posts grows | Can build hundreds of posts within seconds |
Installation | Requires Ruby, Gems, Bundler (complex dependencies) | Single binary executable (ready-to-use upon download) |
Functionality | Plugin-based (limited support on GitHub Pages) | Rich built-in features (shortcodes, image processing) |
Config Files | _config.yml | Supports hugo.toml , hugo.yaml , and hugo.json |
Template Engine | Liquid | Go Template Engine |
1️⃣ Pre-Migration Preparation
🔍 Reviewing Your Existing Jekyll Blog
- Document all configurations and plugins used in
_config.yml
andGemfile
. - Understand your Jekyll directory structure (
_layouts
,_includes
,_posts
,_data
).
💾 Installing Hugo
- macOS:BASH
brew install hugo
* **Windows:**
```bash
winget install Hugo.Hugo.Extended
```
> **Note:** If you plan to customize styles using SCSS, ensure you install the **Extended version** of Hugo.
### 📁 Creating a New Hugo Project
```bash
hugo new site my-hugo-blog
cd my-hugo-blog
git init
```
---
## 2️⃣ Migrating Content
### 📦 Importing Jekyll Posts into Hugo
Hugo provides a built-in Jekyll importer:
```bash
hugo import jekyll /path/to/old-jekyll-site
```
This command transfers markdown files from Jekyll’s `_posts` directory to Hugo’s `content/posts/`, and static assets such as `images` to Hugo’s `static` directory.
### 🛠 Adjusting Front Matter
This step consumed the most time during my migration:
* **Remove the `url:` field:**
Conflicts with Hugo’s permalink settings, so ensure it's removed from all posts.
* **Standardize the date format:**
Use the `YYYY-MM-DD` format for compatibility with Hugo themes.
* **Convert `tags` and `categories` to array format:**
```yaml
tags: ["LLM", "Compiler"]
```
### 🖼 Updating Image Paths
Hugo serves files in the `static/` folder from the root (`/`) directory:
e.g., `static/images/foo.png` → `/images/foo.png`
---
## 3️⃣ Choosing and Applying a Theme
Hugo provides a vast selection of themes. I recommend browsing and testing themes directly from [themes.gohugo.io](https://themes.gohugo.io/).
My key selection criteria were:
* Aesthetic design
* Active maintenance (recent commits)
* Built-in functionality (dark mode, comments, SEO, etc.)
👉 Ultimately, I chose the [**hugo-narrow**](https://themes.gohugo.io/themes/hugo-narrow/) theme. Although it's relatively new, it fits my needs perfectly and offers an appealing design.
### Applying a Theme (Git Submodule method)
```bash
git submodule add https://github.com/<theme-repo> themes/narrow
echo 'theme = "narrow"' >> hugo.toml
```
---
## 4️⃣ Preserving URL Structure (SEO)
If your existing blog content is indexed by search engines, preserving the original URL structure is crucial for SEO.
```toml
[permalinks]
posts = "/:year/:month/:slug/"
```
Then, include the following field in each markdown file’s Front Matter:
```yaml
slug: my-awesome-post
```
This generates permalinks such as `/2023/08/my-awesome-post/`.
---
## 5️⃣ Build and Deployment
### 🔄 Local Server Testing
```bash
hugo server -D
```
* The `-D` option includes draft posts.
* Check your site at `http://localhost:1313`.
### 🚀 Deploying to GitHub Pages
Hugo supports automated deployment via GitHub Actions workflows. Use the following templates for quick setup:
* [Hugo Official GitHub Actions Example](https://github.com/peaceiris/actions-hugo)
> Alternatively, you can use simpler deployment methods through Netlify, Cloudflare Pages, or Vercel.
---
## Conclusion
Migrating to Hugo was much more than just changing technologies—it was an enriching experience overall. The speed, structure, and ease of maintenance Hugo provides allows me to focus more on blogging itself, rather than technical hassles.
If you're currently experiencing slow builds or maintenance issues with Jekyll, I strongly recommend giving Hugo a try. You’ll likely find the migration easier than you expect!
Happy blogging! 🚀
Comments