[Software] · Sep 15, 2026 · 4 min read
Why I built a personal hub instead of another portfolio site

Every developer portfolio I’ve built has died the same way: I ship it, it looks good for a month, and then it quietly falls behind every project it’s supposed to describe. The gap between “what I’m actually working on” and “what the portfolio says I’m working on” only grows, because updating it is a separate chore competing with the work itself.
Hub is what I built instead of accepting that as normal.
The idea
Instead of a static page I remember to edit, Hub is a flat catalog of every product I run or ship — software or not — populated from real development activity. A local LLM reads each tracked repo’s own git history and drafts journey entries and weekly rollups; a stateless digest API turns that into structured content; and everything lands as a reviewable GitHub PR before it publishes anywhere. Nothing goes live without me merging it, but nothing requires me to sit down and write it from scratch either.
Why self-hosted, end to end
I didn’t want a CMS in the loop, and I didn’t want a hosted AI API bill that scales with how much I ship. The two halves of Hub run on two different boxes I already own. A Mac mini handles scheduling and local AI inference — it’s what actually reads git history and drafts journey entries, rollups, and article suggestions. The site itself is a static Astro build, deployed separately onto a BLACKVIEW MP100 (Ryzen 5 7430U, 16GB RAM, 512GB storage) running Ubuntu Server, which is also where the digest API serving that content lives. The tradeoff is setup time up front and two machines to keep running instead of one; the payoff is that the whole system costs nothing ongoing and nothing leaks to a third party.
What “living” actually means here
Concretely, three things happen automatically that used to be manual:
- Per-product journey entries get generated directly from git activity, so a week of real commits becomes a real update without me writing one.
- Weekly and monthly rollups synthesize progress across everything I’m tracking, so the top-level feed reads like a narrative instead of a changelog dump.
- Blog articles get suggested and drafted from that same activity, independently of the rollup. This one isn’t as hands-off as the other two yet — where a journey entry or rollup is close to publish-ready once I’ve reviewed it, a drafted article is more of a starting point: an angle and a first pass I still rewrite and shape myself before it goes out as a real post. This one included.
None of it skips review. Every AI-drafted piece of content is exactly that — a draft — until a PR is read and merged. The automation’s job is to get a reasonable first draft in front of me, not to publish unsupervised.
Where it stands
Hub is live now — the catalog, the journey feed, the blog, all of it running on the setup described above. A large part of it updates itself: journey entries and rollups land as PRs on their own schedule, with review being the only manual step left in the loop. I’m not sitting down to hand-edit the site to keep it honest anymore, which was the entire point.
It’ll keep changing as I do. New entries land as I ship, rollups pick up whatever happened since the last one, and the catalog will keep reflecting not just what’s already built, but what I’m currently working on and what’s next in line — including the smaller, half-formed experiments that haven’t earned a proper product page yet. That’s the actual test of whether this was worth building: not whether it looked good on launch day, but whether it still describes what I’m doing a year from now without me having to remember to update it.