← All posts
Development17 Feb 2026· 3 min read

Building a Markdown-Driven Blog with Zero Dependencies

~/blog/markdown-driven-blog.md

I have a confession: I've been building websites for twenty years, and this blog is the most fun I've had in a long time. Not because it's complex — it's the opposite. It's a handful of HTML files, one CSS stylesheet, one JavaScript file, and a folder full of Markdown. No React. No Next.js. No build step. No CMS login screen.

And it feels great.

Why I went this route

The short answer is that I was tired of fighting tooling. Every blog platform I've used eventually becomes a maintenance burden. The CMS needs updating. The theme breaks after an upgrade. The plugin ecosystem shifts. You spend more time keeping the lights on than actually writing.

I wanted something I could understand completely, end to end. Something where adding a new post means creating a .md file and updating a JSON array. Something that loads fast, costs nothing to host, and doesn't phone home to anyone.

The best architecture is the one you never have to think about. For a personal blog, that means static files.

How it actually works

The engine is about 120 lines of JavaScript in a single file called blog.js. It does three things:

  1. Fetches post metadata from an index.json file — titles, dates, tags, excerpts, filenames
  2. Fetches and parses Markdown files on demand, converting them to HTML client-side
  3. Provides helper functions for rendering post cards, post rows, and formatted dates

The Markdown parser handles headings, bold, italic, links, images, code blocks, blockquotes, lists, and horizontal rules. It's not going to win any awards for edge-case handling, but for blog posts? It's more than enough.

// The entire post-loading flow
const posts = await Blog.getPosts();
const post = posts.find(p => p.slug === slug);
const html = await Blog.getPostContent(post.filename);
document.getElementById('article').innerHTML = html;

Four lines. That's the whole render pipeline.

The design: terminal aesthetic

I wanted the site to feel like my space — not a template. The terminal window chrome (those red, yellow, green dots) wraps content areas and gives everything a dev-native feel. Martian Mono as the sole typeface keeps things consistent and a little unusual.

The blinking eyes in the background are a carry-over from my original site. They're pure SVG with CSS animations — no JavaScript needed. Subtle enough that most people don't notice them for a few seconds. That delay is the whole point.

What I'd do differently

Honestly? Not much. If I were building something with fifty contributors and a content calendar, I'd reach for a headless CMS. But for one person writing a few posts a month, this is the right amount of architecture.

The one thing I might add eventually is client-side search. A small index that lets you filter by keyword without hitting a server. But even that feels like premature optimisation for six posts.


Sometimes the most modern thing you can do is use less technology. This blog is my proof of that. Static files, zero dependencies, and the browser does the rest.

← PreviousAll postsNext →