← All Posts / Engineering NotesJune 2026 / 6 min read / 320 words
Why I Moved This Portfolio's Blog from Static Files to Supabase

Why I Moved This Portfolio's Blog from Static Files to Supabase

A static blog built from local files works fine until publishing a post means a code change and a redeploy. This site started that way, and at some point that workflow stopped matching how often I actually wanted to write.

TL;DR / Written for skimmers

Every new post meant a new file, a commit, and a deploy, which is a fine workflow for occasional writing but a real source of friction for anything more frequent. Editing an old post had the same cost as publishing a brand new one. A hosted headless CMS would have solved the editing problem but added another vendor, another API to learn, and another monthly cost for a personal site that does not need that scale. The schema stayed close to what the site already modeled in code: posts, categories, tags, and a published flag. Moving that shape into Postgres tables was mostly a translation exercise, not a redesign. Publishing a post is now a form submission, not a deploy. That distinction matters more than it sounds, since it removed the small but real activation energy that used to sit between having an idea and publishing it.

What static files were getting in the way of

Every new post meant a new file, a commit, and a deploy, which is a fine workflow for occasional writing but a real source of friction for anything more frequent. Editing an old post had the same cost as publishing a brand new one.

There was also no real query layer. Filtering by category, tagging posts, or building a featured-posts section meant writing logic to read and parse files instead of writing a query.

Picking Postgres over a headless CMS subscription

A hosted headless CMS would have solved the editing problem but added another vendor, another API to learn, and another monthly cost for a personal site that does not need that scale.

Supabase gave the same outcome, a database I can query and an editing surface I control, on infrastructure that also covers auth and storage if this site ever needs either.

What a CMS layer on top of Supabase actually needs

The schema stayed close to what the site already modeled in code: posts, categories, tags, and a published flag. Moving that shape into Postgres tables was mostly a translation exercise, not a redesign.

The part that took real thought was the editing surface itself: a simple authenticated form backed by Server Actions, enough to create and update posts without needing a full admin framework.

What changed for actually writing posts

Publishing a post is now a form submission, not a deploy. That distinction matters more than it sounds, since it removed the small but real activation energy that used to sit between having an idea and publishing it.

The category and tag structure also made the AI-powered search on this blog possible, since both full-text and embedding-based search need rows in a real table to query, not a folder of files to parse on every request.

← All Posts
SupabaseNext.jsCMSEngineering