Choosing Blog CMS
So many CMS softwares, fulfilling their own purpose, the needs of their niche users.
For this blog, I wanted a minimum maintenance system:
- No server processes
- No DB to store data
- No hosting of any kind
- Self-managed as much as possible
With this, the best way to go forward was a Git-based system which stores data in Git and in plain text files. No binary encoding—it’s not going to be asset-heavy like a website; rather, it would be text-heavy, and what handles text better than Git? Also, by storing data as text, I’m avoiding the problem of vendor lock-in.
Initially, I wanted a WYSIWYG editor or Block editor, but later as I explored, I changed my mind. I settled for an Astro-based project, with no prebuilt theme, vanilla CSS and HTML written from scratch.
Data and View/UI
Every CMS system can be categorized into two parts:
- Data layer
- View/UI layer
WordPress and other older systems incorporate both of these into one application. But new systems are separating these into two distinct things. Often, the systems which manage the data part for these systems are called Headless CMS (e.g., Strapi).
Now, these Headless CMSs can itself store data in many different forms and places—like in a DB, or in Git, as binary or as plain text, etc.
Some Headless CMSs do give UI editor support to edit the data, whereas for others you have to build it yourself. And those which do give it mostly use a block-style editor, because they don’t know the exact UI since they don’t know how it’s going to be displayed.
Since these Headless CMSs have to be hosted, they are out of the picture for this project.
View can be anything, from a SPA which is hydrated on the client side (like React), or SSR (like Next.js), to static pages generated by SSG.
The issue with Next.js and other SSR frameworks is they are not static; since they are servers, I need to run them somewhere. Which I didn’t want. So that leaves us with CSR or SSG.
CSR is good for applications with dynamic content, but for static, text-heavy sites, not so much. Lighthouse metrics are always unfavorable to them, which makes sense since everything has to be hydrated on the client side. So the best option for a blog is SSG, and they generate more of a traditional MPA.
SSG
There are many static site generators available: Jekyll, Gatsby, etc. But mostly it’s Hugo nowadays, and Astro is making more leaps. SSGs are great for documentation and blog-like sites.
Hugo or Astro
Hugo is a very fast static site generator written in Golang. It has a vast ecosystem. But it’s a template-based system and, again, it’s written in Go. When creating themes or editing, it’s like trying to work with two ecosystems: JS and Golang.
Nowadays, people are moving towards Astro, which gives more leg room. But Hugo still remains popular for large sites.
Hugo themes are heavily centered on blogs and documentation. Astro themes often cater to marketing, portfolios, and SaaS because they can easily integrate interactive frameworks like React or Vue.
- Hugo: Customizing a theme often requires learning Go Templating and navigating a specific override system, which can have a steep learning curve.
- Astro: Most themes are built using standard JSX-like components. If you know HTML and basic JavaScript, you can usually dive into the code and modify it much more intuitively.
Theme
I cannot settle on any theme for this blog; I felt themes are doing too much, overly convoluted, and just not the “vibes” for this blog. So, as any sane person, I vibe-coded it.
I used Gemini, and it helped me design, choose typography, and then implement the project in the Astro way. Minimal code, Minimal style, full control.
Honorable Mention: Publii
Publii seemed like a good solution:
- Desktop application, no need to run any process/host anywhere.
- Block editor, WYSIWYG editor, no need to manually touch MD files.
- Good theme support out of the box, no need to touch CSS/HTML/JS by hand.
- Generates static files and even has integration to upload to GitHub Pages.
But:
- Data is stored in an SQLite DB.
- Git is not supported for storing the DB; file syncing has to be used (Dropbox, etc.).
Appendix: CSR vs SSR vs SSG
With CSR, much data has to be sent before anything can be rendered/displayed on the screen. Even with Solid.js, which doesn’t use Virtual DOM, it takes time. Data might not include big assets, but all the rendering logic and routing logic has to be in place. Then that big JS code has to be interpreted to generate HTML & CSS. This process of generation is typically called hydration. Since everything is generated on the client side, website metrics become bad. Also, bots cannot understand anything since they don’t execute JS, and because of this, SEO scores drop since there is no page-specific data—there is no page itself until execution.
With SSR, we offload some of this task to the server. It’s like an intermediate mechanism where the server renders or hydrates before sending to the client. It could be configured with per-request hydration but typically does so for the first request for that particular path and serves from cache. Still, it doesn’t alleviate everything from rendering on the client side—some data still gets hydrated there. But it does improve SEO and other metrics.
With SSG, it takes it one step further: content is static and generated at build time rather than runtime. SSGs can be integrated to fetch data from different sources and generate the static files. They can have dynamic interactive content, but the idea is static generation as much as possible.
Refs
- https://web.dev/explore/metrics
- https://web.archive.org/web/20150307201729/http://www.developmentseed.org/blog/2012/07/27/build-cms-free-websites
- https://jamstack.org/headless-cms/
- https://alineacms.com/docs
- https://tina.io/tinadocs/docs/using-tinacms/what-is-tinacms
- https://decapcms.org/docs/working-with-a-local-git-repository/
- https://sveltiacms.app/en/docs/start
- https://keystatic.com/docs/installation-astro#deploying-keystatic-astro
- https://github.com/davidvkimball/vault-cms
- https://github.com/estruyf/vscode-front-matter
- https://github.com/plentico/plenti/tree/master
- https://github.com/apHarmony/jsharmony-cms
- https://www.reddit.com/r/statichosting/comments/1phf593/generating_50k_pages_astro_vs_hugo_vs_11ty/
- https://www.mkumaran.net/2025/migrate-to-astro/
- https://www.jamiekuppens.com/posts/my-experience-migrating-to-astro-from-hugo
- https://www.eliostruyf.com/migration-story-hugo-astro/