> ## Content Index
> Fetch the complete content index at: https://anukulsaini.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How I Migrated anukulsaini.com from WordPress to Ghost CMS — A PM's Case Study
- URL: https://anukulsaini.com/wordpress-to-ghost-migration/
- Published: 2026-03-04T17:25:08.000Z
- Updated: 2026-04-15T08:01:24.000Z
- Description: I rebuilt my entire personal website from scratch — ditching WordPress for Ghost CMS on a self-hosted VPS. Here's everything I did, why I did it, and what I learned as a PM who wanted full control.
- Author: Anukul Saini
- Tags: Case Study

There's a moment every developer and PM eventually hits — the moment where the tool you're using starts feeling like a cage.

For me, that moment came with WordPress.

I'd been running anukulsaini.com on WordPress for a while. It worked. It did the job. But every time I wanted to do something slightly custom — add a tool, create a unique layout, build a members-only section — I was fighting plugins, fighting themes, fighting page builders, and honestly, fighting myself.

So I did what any product manager with too much curiosity and not enough free time would do.

I blew it up and rebuilt it from scratch.

## Why I Left WordPress?

Let me be clear — WordPress is not bad. It powers 40% of the internet for a reason. But for what I wanted to do, it had become the wrong tool.

Here's what was frustrating me:

- **Speed was terrible.** No matter how many caching plugins I stacked, the site felt slow. Every plugin added weight.
- **Customization had a ceiling.** Want something truly custom? You either fight with the block editor, buy a premium plugin, or hire someone to write PHP you'll never fully understand.
- **The admin felt bloated.** I was maintaining updates for 12+ plugins just to run a personal website.
- **Membership and newsletter tools were expensive.** WooCommerce + MemberPress + Mailchimp was going to cost me more than I wanted to spend monthly.
- **I didn't feel in control.** And for a product manager who talks about ownership and autonomy — that felt wrong.

I wanted a platform that got out of my way. Something fast, clean, and extensible. Something I could bend to my will without fighting it every step of the way.

That's when I seriously looked at Ghost.

> The last straw was the [WordPress spam issues that pushed me over the edge](https://anukulsaini.com/wordpress-internal-site-search-spam-solved/) — I’d spent too long firefighting problems that Ghost simply doesn’t have.

## Why Ghost ?

Ghost is an open-source publishing platform built specifically for creators. Unlike WordPress which tries to be everything for everyone, Ghost is laser-focused — fast publishing, native memberships, newsletters, and a clean architecture that doesn't get in your way.

What convinced me:

- **Native memberships and newsletters** built in — no plugins, no third-party tools, no extra cost
- **Handlebars templating** — full control over HTML and CSS without touching PHP
- **Blazing fast** — Ghost is Node.js based and significantly lighter than WordPress
- **Ghost can be self-hosted** — I own my data, my infrastructure, my experience
- **Tier-based paid memberships** — perfect for what I had planned: free tools and paid tools

The plan was clear. Move to Ghost. Self-host it. Build everything custom.

## Setting Up My Own VPS From Scratch

This was the part I was most nervous about and most proud of completing.

I'd never set up a VPS from scratch before. I'm a product manager by profession — not a DevOps engineer. But I've always believed the best PMs have enough technical depth to build things themselves when needed.

So I spun up a VPS, picked my server specs, and got to work.

The first thing I installed was **CloudPanel** — a modern, free server control panel that makes managing a VPS dramatically easier than doing everything raw in the terminal. CloudPanel gives you a clean UI to manage sites, SSL certificates, databases, and more.

Once CloudPanel was running, I used it to install Ghost CMS directly. CloudPanel has a one-click Ghost installer which sets up the entire Ghost environment — Node.js, MySQL, Nginx, SSL — everything configured and production-ready.

What I learned from this:

- VPS setup is intimidating until you do it once. Then it feels obvious.
- CloudPanel is genuinely excellent for anyone who wants self-hosting without becoming a full-time sysadmin
- SSL setup with Let's Encrypt was automatic — took about 30 seconds
- Having your own server means no shared hosting limitations, no surprise traffic throttling, and full control

> Once I migrated, I [automated my Ghost workflow](https://anukulsaini.com/how-i-automated-my-blog/) so the new setup was not just cleaner but faster too.

## Building the Custom Theme

Ghost uses Handlebars templates — `.hbs` files that control every page layout. This was a learning curve coming from WordPress themes, but once it clicked, it felt so much cleaner.

I built my theme entirely from scratch. No starter theme. No template marketplace. Just me, a blank folder, and a design vision.

Here's what I built:

**Homepage** — A full custom layout with a hero section, about section with animated photo and skill tags, a case studies grid with custom metrics per post (pulled from Ghost's code injection per post), a tools section, testimonials, and a newsletter CTA.

**Tools section** — I built each tool as a Ghost page tagged with `tools`. The tools listing page auto-fetches all tagged pages and displays them in a card grid with a price badge (Free / Freemium / Paid) that I control per page via Ghost's code injection — no database, no backend.

**Case studies section** — Each case study is a Ghost post tagged with `case-study`. The listing page fetches metrics (like traffic numbers, revenue impact, build time) from a JSON object I paste in each post's code injection header. A small JavaScript snippet on the listing page fetches each post, reads the JSON, and renders the metrics dynamically — no custom backend needed.

**Work page** — Dedicated listing page (`page-work.hbs`) that pulls all case study posts and renders them in a full-width card grid with feature images, tags, and metric rows.

**Author page** — Custom author template with circular profile photo, bio, social links, and a post grid that filters out case studies automatically.

**Tag pages** — Smart tag routing: `/tag/case-study` redirects to `/work`, `/tag/tools` redirects to `/tools`, and all other tags get a clean generic listing page.

Every template was Ghost-native — using `{{#get}}`, `{{#foreach}}`, `{{#has}}`, `{{codeinjection_head}}`, and `{{#is}}` helpers properly. No JavaScript hacks to work around the templating system.

## Building the Tools

This was the most exciting part for me as a PM. I didn't just want a portfolio website — I wanted a platform that actually helped people.

I started building browser-based tools that run 100% client-side. No server, no database, no API costs. Just HTML, CSS, and JavaScript embedded directly into Ghost pages.

**Tool 1: Word Counter & Readability Checker**  
The first tool I shipped. Paste any text and instantly get word count, character count, sentence count, readability scores (Flesch-Kincaid), reading time, speaking time, and more. Built entirely in vanilla JS — no dependencies.

**Tool 2: JSON Formatter & Viewer**  
A full-featured JSON tool with beautify, minify, validate, sort keys, load from URL, upload from file, download, and an interactive collapsible tree viewer. Color-coded output for keys, strings, numbers, and booleans.

Each tool gets its own Ghost page with:

- The tool embedded via HTML block
- Full SEO content explaining what the tool does and how to use it
- Meta title, description, and excerpt set in Ghost
- Price badge set via code injection

The plan is to expand this into a full tools directory — image converters, case converters, JSON tools, SEO tools, UTM builders, favicon generators, and eventually paid tools behind Ghost's native membership paywall.

## What Ghost Gives Me That WordPress Couldn't

| Feature                 | WordPress                     | Ghost               |
| ----------------------- | ----------------------------- | ------------------- |
| Native newsletter       | Plugin (Mailchimp/ConvertKit) | ✅ Built in          |
| Native memberships      | Plugin (MemberPress $$$)      | ✅ Built in          |
| Paid tiers              | Plugin stack required         | ✅ Native            |
| Page speed              | Plugin-dependent              | ✅ Fast by default   |
| Custom templates        | PHP + hooks                   | ✅ Clean Handlebars  |
| Self-hosting cost       | Hosting + plugins             | ✅ VPS only          |
| Code injection per page | Not native                    | ✅ Native            |
| Content API             | REST (complex)                | ✅ Clean Content API |

## Challenges I Faced

I'm not going to pretend this was smooth sailing.

**Ghost templating has quirks.** Nested `{{#has}}` blocks don't work the way you'd expect — Ghost falls through to the last else. I learned this the hard way when my price badges were all showing "Free" regardless of what tag I set. The fix was using separate independent `{{#has}}` blocks.

**Self-hosting is responsibility.** When something breaks at 2am, there's no support ticket to raise. You're the sysadmin. I had to learn enough about Nginx, Node processes, and CloudPanel to debug issues myself.

**Ghost's `{{#get}}` has limitations.** You can't do complex relational queries. I worked around this creatively — using slug exclusions (`slug:-tools`) to prevent the listing page from appearing in its own grid, and using code injection JSON for per-post metrics instead of a database.

**No page builder.** Ghost's editor is clean but minimal. If you want complex custom layouts, you build them in HTML blocks. This is a feature for me, but it would be a blocker for non-technical users.

**CSS specificity fights.** Building a theme from scratch means you own every CSS decision. That's powerful but also means there's no safety net — a wrong selector and things break silently.

> Part of what made WordPress unsustainable was [chasing too many WordPress plugins](https://anukulsaini.com/why-over-optimizing-is-bad/) — a trap I explain in detail in another post.

## My Learnings as a PM

Building this taught me things no product management course ever could.

**Constraints breed creativity.** Not having a plugin for everything forced me to think from first principles. Ghost's code injection per page became my entire dynamic data system. No backend needed.

**Ship fast, iterate faster.** I launched with one tool, one case study, and a rough homepage. Every day since has been an iteration. Done is better than perfect — especially for a personal site.

**Technical depth compounds.** Every hour I spent understanding Ghost templating, Nginx configs, and VPS setup has made me a better PM. I now speak the language of infrastructure engineers with more confidence.

**Own your platform.** SaaS tools can change pricing, deprecate features, or shut down overnight. Owning my server, my code, and my data means nobody can take this away from me.

**Design is a product decision.** Every layout choice — the 40/60 split on the about section, the floating pills, the metrics on case study cards — was a product decision with a user in mind. My visitors are PMs, engineers, and founders. They expect clean, fast, and credible.

## What's Coming Next?

This is version 1\. Here's what I'm building next:

- **More tools** — Image compressor, WebP converter, Case converter, UTM builder, Meta tag generator, Base64 encoder, Regex tester, Favicon generator
- **Paid tools tier** — Ghost's native membership system will gate premium tools behind a subscription
- **Newsletter** — Weekly drops for PMs and engineers — tools, frameworks, and growth tactics
- **More case studies** — Detailed breakdowns of products I've built and grown with real numbers
- **Performance dashboard** — A public page showing real traffic, subscriber, and revenue numbers

## A Note on Numbers

I'll be honest — I'm not going to make up metrics to make this case study look impressive.

The migration is fresh. The tools are new. The SEO is still cooking.

I will keep this case study updated as real data comes in — traffic growth, tool usage, subscriber numbers, and any revenue driven through paid memberships. That's the kind of transparency I'd want from a case study I was reading, so that's what I'll give you here.

Check back. The numbers are coming.

---

*Built with Ghost CMS, self-hosted on a VPS with CloudPanel, designed and developed entirely by me. If you're a PM thinking about doing something similar — feel free to reach out. I'm happy to share exactly how I did it.*