AI-Powered Blogging Platform

My brother is a digital marketer. He had built a real following on Instagram — the kind of audience that can actually convert to a newsletter or a blog readership. He came to me in late 2024 with a practical ask: "Build me a blog so I can monetize it through content and referral revenue." Simple enough on the surface.
The complication was that I am constitutionally incapable of reaching for the simplest tool when I can see the assumptions baked into that tool are wrong for my situation. I tried three stacks before I committed to building custom.
First iteration: Hygraph as a headless CMS. It works fine until you want anything that feels like a real blogging experience — the editor is a form, not a writing environment. My brother would have abandoned it in a week. Second: Sanity. Better, but the studio is a separate application, the costs add up with usage, and the customisation ceiling is real. Third: Faust.js on top of WordPress. WordPress has all the features, but the codebase is the kind of thing that makes you feel tired before you've written a single line of your own code.
After three failed iterations I asked the question I should have asked first: what are people actually paying for in the blogging-platform market, and does that match what they need?
Ghost Pro is $25/month minimum. Hashnode is free but locks you into their infrastructure with no real escape hatch. Both have something in common: you are renting features built for the median content creator, not owning an asset. The thesis that crystallised around November 2024: if I build something that matches Hashnode feature-for-feature and ship it as a ThemeForest product, I get two things simultaneously — my brother gets his blog, and I get passive income from a product that solves a real problem at a price point ($59–$299) that makes immediate sense to anyone currently paying Ghost Pro rates.
That was the decision. What followed was 17 months I did not fully anticipate.
The scope was always bigger than "a blog." A blog for a digital marketer who wants to earn money through referrals needs: subscriber management, a writing experience that doesn't feel like filling out a form, control over how the site looks, email newsletters, SEO metadata management, and some way for readers to discover content they haven't searched for yet.
And it needed to be something a non-technical buyer could install and run. That last constraint shaped nearly every architecture decision that followed.
The first version of the installation flow was a series of environment variables you had to fill out yourself. I gave it to my brother on a staging server. He stared at it for thirty seconds and messaged me a confused emoji. That was the clearest possible signal: the product needed a wizard. I built a 7-step installation wizard that walks through database connection, storage configuration, SMTP settings, and initial admin account creation — the kind of thing you get with WordPress but that almost no modern Next.js starter provides.
The editor was the other forcing function. TipTap with 14 extensions: slash commands, drag-and-drop block reordering, inline images, code blocks with syntax highlighting, embeds, callouts, tables. Getting slash commands to feel right took longer than I expected — the UX detail of "type / and get a floating menu that filters as you type" sounds simple until you are handling keyboard navigation, scroll position, and dismiss-on-click simultaneously across mobile and desktop. I kept the Notion editor open in another tab for reference the entire time I was building it.
Authentication model: Better Auth with a 7-role hierarchy — super_admin, admin, editor, author, moderator, premium, user — backed by 42 granular permissions. This feels like over-engineering until you actually run a multi-author publication. Who can publish without review? Who can see analytics? Who can manage subscribers? These questions come up immediately. Baking the permission model in from the start meant I never had to do an awkward migration later. The RBAC surface ended up at roughly 294 active permission checks across the application.
Search: Two layers. Typesense handles full-text search with typo tolerance and instant results — the kind of search that returns results before the user has finished typing. Qdrant handles semantic/vector search, so a reader searching for "dealing with difficult clients" can find an article titled "Managing Stakeholder Expectations" without exact keyword overlap. For a blog targeting a content-marketing audience, semantic search is not a nice-to-have; it is the difference between a post getting discovered three months after publication and getting buried.
Storage: MinIO for object storage. Self-hosting instinct again — why pay per-GB for S3 when you control the server? MinIO speaks the S3 API so the application code doesn't care which backend is running. On a VPS, the cost difference is significant.
Real-time: Soketi (a self-hosted Pusher-compatible WebSocket server) for live notifications and collaborative cursors. This is the feature that most blogging platforms skip. It is also the feature that, when it works, makes the product feel genuinely different from "just another blog."
Payments: Stripe for subscription billing and paid-content gating. The payment layer is abstracted behind a provider interface so a buyer can swap in their own gateway, but Stripe is the one that ships wired and tested — a single, well-understood path beats three half-integrated ones for a product a non-technical buyer has to deploy.
Infrastructure: Docker Compose for single-server deployments (the most common ThemeForest buyer scenario) with Kubernetes manifests available for teams that need horizontal scaling. I wasn't going to sell a product to a solo blogger and require them to manage a Kubernetes cluster. But I also wasn't going to cap the product's potential by making K8s an afterthought.
The 17-month timeline is not because I was working on this full-time. It is not, though — my main job and other client work took priority in blocks. What I underestimated was the surface area of "feature parity with Hashnode." Every time I thought I was two weeks from done, I would open Hashnode and find another ten things: custom widgets, series/collections, reading progress indicators, RSS feed configuration, canonical URL management, per-post OG image generation.
I also underestimated the testing burden. 92 Jest tests sounds like a reasonable number until you realise that the RBAC system alone needs a test matrix of N roles × M permissions × K resource states to have any confidence that a new permission doesn't accidentally cascade. I wrote the tests that felt obviously necessary and deferred the rest. That is the honest version of "92 tests."
The Lighthouse performance score is 73. Everything else — accessibility (100), best practices (100), SEO (100) — is where I want it. The performance gap is mostly large images and the initial TipTap bundle. I have a task open for it. A performance score of 73 does not ship a broken product; it ships a product with known debt, which is a different thing.
The endDate in the frontmatter is March 2026. The product is not finished in the sense that Ghost Pro is finished. It is finished in the sense that my brother's blog is running on it, it is listed on ThemeForest, and the feature gap between Karmpath and Hashnode is small enough that I can describe it with specifics rather than hand-waving.
~74K lines of TypeScript across 154 commits. A 7-step installation wizard that a non-developer can complete in under 15 minutes. An editor with 14 extensions that my brother uses without asking me questions about it. A 7-role × 42-permission access control system. Full-text search via Typesense and semantic search via Qdrant. S3-compatible object storage on MinIO. Real-time WebSockets via Soketi. Stripe subscription billing wired and tested behind a swappable provider interface. Docker Compose + Kubernetes manifests. 92 tests. Lighthouse: a11y 100, BP 100, SEO 100, perf 73.
Ghost Pro parity on features, at the cost of hosting your own VPS instead of paying $25/month minimum. On ThemeForest: $59 for a regular license, $299 for extended.
The two-birds calculation worked. My brother has his blog. I have a product.
The default assumption in 2024, if you want to start a blog, is to reach for an existing platform. That assumption is correct for most people — Ghost, Hashnode, and Substack exist because the majority of content creators benefit more from a polished SaaS than from infrastructure control.
But the assumption breaks down in specific conditions. If you want to sell the platform itself, not just use it. If you want semantic search, not just keyword search. If you want to own the subscriber relationship completely. If you want to swap in your own payment gateway rather than be locked to one. If you want to charge per-seat rather than per-send for email.
I checked whether the defaults were optimal for my brother's situation and for a ThemeForest product. They were not. So I built the evidence across 17 months — 25+ named development phases, every architectural decision documented against an alternative I considered and rejected — and then shipped the thing.
The judgment I take from this is not "always build custom." The judgment is: before you accept the default, ask who that default was designed for, and whether that person's constraints match yours. If the answer is yes, use the default and ship faster. If the answer is no, you now know exactly what you're signing up for.
25+ named phases
Lighthouse a11y/BP/SEO
ThemeForest product
SSR performance with a mature ecosystem, better Vercel integration, and broader community support for plugins and middleware
Relational data model for user-post-recommendation relationships, ACID compliance, and mature full-text search capabilities
Persistent caching layer with pub/sub for real-time invalidation, data structures for leaderboards, and built-in expiry policies
Response Time
Concurrent Users
Headless WordPress blog with Faust.js, WPGraphQL, Apollo, Tiptap editor, and self-hosted Coolify deployment
XState-driven PMS for real property deployment
Multi-profile Next.js 16 platform — portfolio surfaces + full admin OS underneath
Did this resonate?