Published: June 08, 2025 at 08:45 PM PDT | Updated: June 08, 2025 at 08:49 PM PDT
This article walks through how I built a fully decentralized blog using Nostr as the backend CMS, GitHub Actions for automation, and GitHub Pages for free global hosting. No servers, no logins — just sovereign publishing on open protocols.
🧡 My first post on a fully sovereign blog.
This blog post isn’t hosted on Medium, Substack, or WordPress. It doesn’t live on a database I don’t control. There’s no login, no admin panel, no SaaS dashboard.
Instead, this post was published as a Nostr event — stored on dozens of relays, fetched with open-source scripts, rendered as a static HTML file, and served globally via GitHub Pages.
And it all runs without a single server I have to manage.
Let me show you how it works — and why this matters.
I use Primal.net to write my articles.
Their long-form editor lets you add titles, summaries, and tags to a special kind of Nostr event (30023
).
You just click publish — and the article propagates across the Nostr network.
On my GitHub repo, I maintain a script called fetch_articles.py
.
It connects to multiple Nostr relays (like relay.damus.io
, relay.primal.net
, nostr.mom
, etc.) and fetches any articles I've written using my public key.
Only posts tagged with blog
or article
are kept.
Each article is:
Deduplicated
Parsed for title, summary, image, tags, and content
Converted from Markdown to clean HTML
Saved in a static folder
The output goes straight into the docs/
folder of my public GitHub repository.
Thanks to GitHub Pages, the site is instantly deployed as a static website.
The homepage (index.html
) uses JavaScript to read articles/index.json
and display the 10 most recent blog posts — each linking to its full static HTML page.
To keep things fresh, I created a GitHub Action called Fetch and Build Articles
.
It runs daily — or whenever I trigger it manually — and fetches new content from Nostr, updates the site, and redeploys everything.
No databases. No plugins. No backend headaches. Just content — and the open protocols that carry it.
Most blogs are brittle. Lose your password, your server, or your platform — and your voice disappears.
This setup flips that on its head:
I own my content — It's stored on a public, censorship-resistant network.
Anyone can verify it — The data lives on Nostr relays, signed with my pubkey.
It costs nothing to host — GitHub Pages serves everything statically.
It’s future-proof — If GitHub disappeared, I could mirror the repo anywhere.
This is what publishing should look like in 2025.
You can fork the repo I use here — or read the code and set it up for your own Nostr pubkey.
If you’re not on Nostr yet, you can find me at:
🧬 npub19wvckp8z58lxs4djuz43pwujka6tthaq77yjd3axttsgppnj0ersgdguvd
This is just the beginning. One post, one block, one step at a time — on our own terms.