Every blog I have owned before this one died the same way. Not because I ran out of things to write - I never do - but because the act of publishing had friction. Log into a CMS I did not control, fight an editor that fights markdown, wait for a rebuild, click publish on a platform that will bury the post anyway. Somewhere between the thought and the article, the energy dies.
So I built BuildLog. One rule behind the whole project: the distance between "I have a thought" and "it is live on the internet" has to be shorter than the thought's half-life. This post is the full tour - what it does, what runs it, and why.
What you are looking at
BuildLog is a personal developer journal with two halves.
The public side is what you are reading: server-rendered articles and project case studies with highlighted code, a table of contents that follows your scroll, reading time and view counts, dark mode, keyboard-driven search (Ctrl+K), and threaded comments under every piece.
The private side at /admin is a complete CMS: write in markdown with a live preview, save as draft, publish, pull back, feature on the homepage, set the publish date, rename the URL, moderate every comment - all from a web page, on my phone, without touching git or a terminal.
The whole thing runs on free tiers: Vercel for hosting, MongoDB Atlas for data, GitHub for identity. The only recurring cost is the domain.
The writing pipeline
Articles and case studies are stored as MDX documents in MongoDB - not markdown files in a repo. That one decision shapes everything else.
Publishing is an API call, not a git push. The admin writes a document, the cache layer invalidates exactly what changed, and the live page is fresh within a second. No CI wait, no commit messages to myself at 1am. The editor's Preview tab runs the same render pipeline the live site uses, so what I see while writing is literally what you get - code highlighting included.
Code blocks are tokenized by Shiki, the engine VS Code itself uses, with light and dark themes compiled in one pass; the theme flip in dark mode is pure CSS, no re-render. And the table of contents is built in the same compilation pass that assigns heading anchors, which means a contents link can never point at a heading that does not exist. That entire category of bug is designed out.
Auth: no passwords, nowhere
There is no user table with hashed passwords, and there never will be. Admin login and the comment system both run on GitHub OAuth. If GitHub vouches for you, this site does.
That single integration buys three things. Nothing here can be leaked, brute-forced, or reused from someone else's breach, because there are no credentials to steal. Every commenter is a real GitHub identity - the comment box does not even render for anonymous visitors, and trolling a blog whose login is your public GitHub profile is a commitment nobody makes lightly. And the admin gate is one email allowlist, re-checked on every write request at the API level - not just at the page shell.
The comment engine, hand-built on purpose
Third-party comment widgets are how blogs quietly fund someone else's ad network. This one is a database collection, one API, and one widget: threaded replies, a moderator like that surfaces as a public badge, one reply per thread, a posting throttle that keeps drive-by spam out, and a moderation console where every conversation sits grouped under its article. Likes, replies, edits and deletes all resolve without a page refresh.
Readers cannot edit or delete their comments on-site - that is deliberate. A personal blog is not a forum, and comment mutation rights are how a thoughtful thread turns into a bait-and-switch.
Under the hood: reads are cached, writes are instant
The performance model fits in one sentence: every public read is cached and tagged, and every write busts exactly the tags it invalidates.
Home, article, project and search pages all read through cached data layers. When I publish, the mutation invalidates precisely those cache entries - the stale page is gone before the "saved" toast finishes animating. A page load that hits a warm cache runs zero database queries, which is how the entire site lives comfortably inside a free database tier.
The editor itself has a double safety net for the one failure every writer fears. Text autosaves to browser storage continuously, and if I leave an unsaved form mid-thought, the CMS offers to persist it as a real draft before I go. Nothing gets lost to a mistyped click.
The look: brutalism, but disciplined
Neo-brutalist - two-pixel ink borders, hard shadows with no blur, buttons that press into the page when you click them, code inside terminal windows. It is a deliberate call: a text-heavy site should feel like it contains objects, not just paragraphs.
Underneath, it is a real system - a fixed set of semantic color and type variables that every component consumes, with dark mode as a single block of overrides. Nothing is hardcoded, so nothing drifts. A component either speaks the design language or visibly sticks out, and that is the entire enforcement mechanism.
See it, read the code
The live site is BuildLog. The repository is public at RajHarsh03/BuildLog - if you are thinking of building something like this, the source is the long version of this post.
And the comment section below this article works exactly like everything described above. Sign in with GitHub and try it - that is the point.


forumComments
0 comments