1. Why Build a Personal Blog
A personal blog gives you several things that third-party platforms can’t:
- A knowledge base you actually own. Writing things up forces you to organize your thinking, and you’ll thank yourself later when you need to look something up.
- A public portfolio. Potential employers, collaborators, or clients can see how you think and what you know.
- Full control. No algorithm changes, no platform shutdowns, no content policy surprises. It’s yours.
- Near-zero cost. GitHub Pages hosts static sites for free.
There are plenty of static site generators out there — Hugo, Jekyll, Hexo, WordPress, and more. I went with Hexo because it runs on Node.js, which I was already familiar with, and it checks all the boxes:
- Fast static page generation
- A large selection of themes with deep customization options
- Markdown-first writing
- One-command deployment to GitHub Pages
This guide walks through the entire process from scratch.
2. Prerequisites
2.1 Install Node.js
Hexo requires Node.js. Head to the Node.js website and grab the LTS release — 18.x or 20.x will work fine. Run the installer and accept the defaults.
Verify the installation:
Open a terminal and run:
1 | node -v |
You should see version numbers printed back:

2.2 Install Git
You’ll need Git to push your blog to GitHub. Download it from git-scm.com and install with the default options.
Verify:
1 | git --version |
If it prints a version number, you’re good.
2.3 Set Up a GitHub Account and SSH Keys
If you don’t already have one, sign up at GitHub. Then set up SSH keys so you can deploy without typing your password every time.
Generate an SSH key pair:
1 | # Set your Git identity |
Hit Enter three times to accept the defaults. Your keys land in ~/.ssh/ (on Windows, that’s C:\Users\YourName\.ssh).
Add the public key to GitHub:
- Open
~/.ssh/id_rsa.puband copy everything in it - On GitHub, go to Settings → SSH and GPG keys → New SSH key
- Paste the key and save
Test the connection:
1 | ssh -T git@github.com |
If you see Hi YourName! You've successfully authenticated..., you’re all set.
3. Install Hexo
3.1 Create a Project Directory
Pick somewhere to keep your blog files. I’ll use D:\Blog for this guide:
1 | D: |
3.2 Install the Hexo CLI
1 | npm install -g hexo-cli |
Verify:
1 | hexo -v |
3.3 Initialize the Blog
1 | hexo init blog |
After initialization, your directory looks like this:
1 | blog |
3.4 Preview Locally
1 | hexo server |
Open http://localhost:4000 in your browser. You should see the default Hexo landing page:

Press Ctrl + C to stop the server.
4. Set Up GitHub Pages
4.1 Create the Repository
- On GitHub, click “+” → “New repository”
- Name it
yourusername.github.io(replace with your actual username) - Set it to Public
- Click Create repository
The repository name must follow the
username.github.iopattern — that’s how GitHub Pages knows it’s a user site.

4.2 Configure Deployment
Open _config.yml in your blog’s root directory. Find the deploy section and update it:
1 | # Deployment |
For example, if your username is donehub:
1 | deploy: |
4.3 Install the Deploy Plugin
1 | npm install hexo-deployer-git --save |
5. Configure the Site
5.1 Update Site Metadata
Open _config.yml and fill in your details:
1 | # Site |
5.2 Key Commands
| Command | Shortcut | What it does |
|---|---|---|
hexo new "Post Title" |
hexo n "Post Title" |
Create a new post |
hexo generate |
hexo g |
Build static files |
hexo server |
hexo s |
Start local preview server |
hexo deploy |
hexo d |
Push to GitHub Pages |
hexo clean |
— | Clear the cache |
The most common combo:
1 | hexo clean && hexo g && hexo d |
6. Install a Theme
The default Hexo theme is bare-bones. I’d recommend NexT — it’s clean, well-maintained, and highly configurable.
6.1 Install NexT
1 | npm install hexo-theme-next --save |
Or clone it directly:
1 | cd blog |
6.2 Activate the Theme
In _config.yml, change:
1 | theme: next |
6.3 Theme Configuration
NexT has its own config file. Create _config.next.yml in the site root:
1 | # Pick a layout scheme |
6.4 Create Category and Tag Pages
1 | hexo new page categories |
Edit source/categories/index.md:
1 | --- |
Edit source/tags/index.md:
1 | --- |
7. Writing Posts
7.1 Create a Post
1 | hexo new "My First Post" |
This creates source/_posts/My-First-Post.md.
7.2 Post Structure
Every post starts with a Front Matter block:
1 | --- |
7.3 Markdown Cheat Sheet
| Syntax | Result |
|---|---|
# Heading |
H1 |
## Heading |
H2 |
**bold** |
bold |
*italic* |
italic |
[link text](url) |
Hyperlink |
 |
Image |
`inline code` |
Inline code |
```lang code block ``` |
Fenced code block |
> blockquote |
Blockquote |
- item |
Unordered list |
1. item |
Ordered list |
7.4 Working with Images
Option 1: Use an image host
An image host gives you stable URLs that you can reference from anywhere. This keeps your repo small and your pages fast.
📖 Related reading: Building a Personal Image Host with PicGo and Gitee — covers setting up a free image hosting solution using PicGo and a Gitee repository.
1 |  |
Option 2: Store images locally
Enable post asset folders in _config.yml:
1 | post_asset_folder: true |
Now hexo new "My Post" also creates a My-Post/ folder next to the markdown file. Drop images there and reference them with:
1 | {% asset_img example.jpg Caption text %} |
8. Deploy
8.1 First Deploy
1 | hexo clean |
Or all at once:
1 | hexo clean && hexo g && hexo d |
8.2 Visit Your Blog
After deploying, your blog is live at https://yourusername.github.io.
The first deployment can take a few minutes to propagate.
8.3 Updating
Every time you change a post or config, redeploy:
1 | hexo clean && hexo g && hexo d |
9. Custom Domain (Optional)
If you own a domain, you can point it at your GitHub Pages site for a cleaner URL.
📖 Related reading: Binding a Custom Domain to GitHub Pages — walks through CNAME setup, DNS records (A and CNAME), and HTTPS configuration.
9.1 Add a CNAME File
Create a file called CNAME (no extension) in the source/ directory:
1 | www.yourdomain.com |
9.2 Configure DNS
Add these records at your domain registrar:
| Type | Host | Value |
|---|---|---|
| CNAME | www | yourusername.github.io |
| A | @ | 185.199.108.153 |
| A | @ | 185.199.109.153 |
| A | @ | 185.199.110.153 |
| A | @ | 185.199.111.153 |
9.3 Enable HTTPS
- Go to your repo → Settings → Pages
- Enter your domain under Custom domain
- Check Enforce HTTPS
10. Useful Plugins
10.1 Recommended Packages
1 | # Sitemap for SEO |
Add to _config.yml:
1 | # Sitemap |
10.2 Enable Search in NexT
In _config.next.yml:
1 | local_search: |
📖 Related reading: Integrating Search into NexT — detailed setup for NexT’s Local Search, covering title and content indexing.
10.3 Add Visitor Statistics
Busuanzi is a lightweight analytics counter:
1 | # In _config.next.yml |
11. Troubleshooting
11.1 Deploy Fails with “Deployer not found: git”
Install the Git deployer:
1 | npm install hexo-deployer-git --save |
11.2 Styles Missing After Deploy
Local preview looks fine but the live site has no CSS. Check _config.yml:
1 | url: https://yourusername.github.io |
A wrong url or root value breaks all asset paths.
11.3 Garbled Characters
Your editor is saving files in a non-UTF-8 encoding. Switch your editor (VS Code, for example) to save as UTF-8.
11.4 New Post Doesn’t Show Up
- Make sure the file is in
source/_posts/ - Verify the Front Matter is valid YAML
- Run
hexo clean && hexo gto force a rebuild
12. Wrap-Up
By now you’ve covered the full workflow: installing Hexo, setting up a GitHub Pages repo, configuring the NexT theme, writing in Markdown, deploying, and adding a custom domain. You also have a few plugins for search, RSS, and analytics. From here, the best thing to do is start writing — the rest will come naturally.