1 min read

Hello, world — this blog is HTML all the way down

Why I store posts as plain HTML in git, and how a small design engine turns any markup into a page that matches my portfolio.

Welcome to the blog. Every post here is a plain index.html fragment plus a tiny meta.json, committed to git. No database, no CMS, no markdown pipeline quietly mangling my markup.

Why HTML instead of markdown?

Markdown is great until it isn't. Tables with merged cells, callouts, embedded video, custom figures — you end up escaping into raw HTML anyway. So this blog skips the middleman: posts are HTML, and a small design engine makes them look right.

Write whatever markup the post needs. The design engine makes it match the site.

How the design engine works

  1. At build time, each post's HTML is sanitized — scripts, inline styles, and foreign classes are stripped.
  2. The clean markup renders inside a themed reading shell where every element — headings, links, lists, quotes, code, tables, images — is styled to match the portfolio's purple palette.
  3. The whole site exports to static files and deploys from a git push.

Code looks like this

def design_engine(html: str) -> str:
    """Any HTML in, on-brand page out."""
    clean = sanitize(html)          # strip scripts + inline styles
    return render(clean, theme="purple")

Tables work too

ApproachStorageFidelity
MarkdowngitLossy for rich layouts
CMS + databasehosted DBHigh, but heavy
HTML in gitgitExactly what I wrote

That's the whole system. Posts land here first — subscribe via RSS if that's your thing, or find me on sameershanbhag.com.