← Home

How This Website Works

This website is my Obsidian vault. Every page — the homepage, project pages, this post — is just a markdown note I wrote for myself and then flipped a switch on. The switch is published: true in the frontmatter. That's the whole publishing model.

I didn't want a CMS. I didn't want a static site generator with a content directory of its own. I already write every day in Obsidian, and I wanted to keep writing there, the same way, with the same wikilinks to the same notes. The site should just be a view into the subset I decide to make public.

How it Builds

There's a Python script called publish.py that does the build. I run it, or a cron job runs it every five minutes, and it does four things.

First, it loads every .md file under Notes/ and parses the frontmatter. Then it filters down to the ones with published: true. Everything else stays private. It renders the body through mistune, rewriting wikilinks along the way — links between published notes become real anchors, and links pointing at unpublished notes become plain text, so you can't accidentally leak a stub. For each published page it also collects the backlinks from other published pages and appends them at the bottom, which is the same "linked to this note" panel I see inside Obsidian. Finally it feeds everything through a pair of jinja2 templates and writes flat HTML files.

No categories, no page types, no nested directories. Every page is at the root. The homepage links to whatever I want to feature, and backlinks handle the rest.

No Build Tools, no Framework

The output is plain HTML and CSS. No JavaScript framework, no bundler, no SSG, no deploy pipeline beyond the cron job. The whole stack is mistune and jinja2. It's the smallest setup I could build that still did the thing I wanted.

The cron job pulls the latest vault, runs publish.py, and pushes the changed HTML back to the repo. If nothing changed, it does nothing. If something changed, the site is up to date within a few minutes.

Why This way

The point of writing in Obsidian is that my notes connect. I can start from an idea I had last year and follow wikilinks to related thinking. A CMS would have made me keep a second copy of things, and the copies would have drifted. A static site generator with its own content directory would have meant deciding, up front, which notes were "posts" — but that's not how I write. I don't know a note is worth publishing until I've had it around for a while.

A checkbox in the frontmatter is the lowest-friction way I could find to handle that. The vault stays a vault. The website is just a view into the parts I chose to share.