How I built this blog (and why I stopped overengineering it)
This is a mini tutorial and a gentle reminder to keep things simple.
The overengineer awakens
Like many engineers with too much curiosity and not enough constraint, I started building my blog from scratch.
My initial setup was:
The idea I had was:
- markdown-based content
- real-time preview
- full customization
- Unlimited Power™
I spent quite some time learning about Next.js folder structure, configuring content collections for Keystatic, thinking about image optimization, theming, deployment… It started to feel like a second job. My website worked, but it was quite heavy for what it was doing. It became clear to me that I should just start with the most simple design I could possibly think of, which doesn’t take my mind away from writing itself.
Enter obsidian + Hugo
This is, of course, a bit more setup than just pure HTML / CSS website you would do in 2000, but nevertheless: Leo, my partner, sent me this blog post.
I decided to replicate this simple workflow:
- write in Obsidian - which I already use daily for notes
- organize posts with frontmatter
- sync to a folder
- publish with Hugo through Netlify
It worked smoothly and took just a bit more than 1 hour to set up. Maintaining and adding features to this site would also be straightforward, since all the content is in Markdown, and any settings can be controlled by frontmatter.
Tutorial (a small one)
These steps outline what I did. There are many other ways to set up your content management, hosting, CI/CD pipeline, etc. You may be happier self-hosting everything at home, or using a more sophisticated setup.
Install Hugo
I use Homebrew:
brew install hugo
Confirm it worked:
hugo version
Create a new site
hugo new site my-blog
cd my-blog
Add the theme (i chose Bearblog initially)
git init
git submodule add https://github.com/janraasch/hugo-bearblog themes/hugo-bearblog
then, update hugo.toml (or config.toml) with the theme:
theme = "hugo-bearblog"
Create your first post
hugo new blog/hello-world.md
you’ll find the file in content/blog/hello-world.md.
Connect Obsidian
Connect Obsidian to content/ folder, or just use any text editor pointing to your target folder, and fill in the frontmatter (tips on how to add frontmatter to Obsidian note here):
---
title: "hello world"
date: 2025-04-24
draft: true
---
Note that draft field is what Hugo looks at to decide whether a post should be published or hidden. Set draft to false to publish the post.
Run your site locally
hugo server -D
Open your browser at http://localhost:1313.
Add a favicon (optional)
Drop favicon.ico into the static/ folder and favicon.png into the static/images folder.
You may also want to tweak the header layout of your site (I added the same image used for favicon next to my blog title).
If you want to make changes to layout (optional)
You can fully customize the look and feel of your site. Let’s take an example of appending an image to site’s title. Inspect the theme you use - notice where the title is placed:
<a href="{{ "" | relURL }}" class="title">
<h2>{{ .Site.Title }}</h2>
</a>
<nav>{{- partial "nav.html" . -}}</nav>
To change header layout partial for your version of the site, you’ll just need to copy this file to your own layouts/partials folder, and change it as you like, for example:
mkdir -p layouts/partials
cp themes/hugo-bearblog/layouts/partials/header.html layouts/partials/header.html
<a href="{{ "" | relURL }}" class="title" style="display: flex; align-items: center; gap: 10px;">
<h2>{{ .Site.Title }}</h2>
<img src="/images/favicon.png" alt="favicon" width="50" height="50">
</a>
<nav>{{- partial "nav.html" . -}}</nav>
Add index (home) page content
Add _ index.md file to the content/ folder and treat it as any other MD file. Add some welcome information about your blog there.
#### Hey, this is my blog!
Welcome :)
Deploy (i used Netlify)
You can push your repo to GitHub and connect it to Netlify or any other product, or self-host your site.
For build, you can use
hugo --minify
To generate the public/ folder with minified html for static hosting anywhere.
with Netlify, i added a netlify.toml config, where i set target version of Hugo to use:
[build.environment]
HUGO_VERSION = "0.146.7"
HUGO_ENV = "production"
Conclusion
Sometimes, building things from scratch is fun. Sometimes, it’s a creativity trap.
Tools should help you do the thing – not get in the way of it. I might keep adding features to the blog - my next steps would probably be image support and language toggle. I will write how I did it if I do.
Appendix
Tools I used:
- Obsidian
- Hugo
- Bearblog theme
- Netlify
- This post for inspiration
P.S. I’ll probably still overengineer something again in the future.