Moving from WordPress to NextJS

After almost a decade serving my (languished) personal site from WordPress, I decided to mix things up a little for the next version. I still love WordPress and develop with it all day, every day at work, but I was ready for a change at home.

Several forces shaped the desire for this change. Perhaps most importantly, I've been using React a lot more lately. I've been enjoying the ecosystem and its affordances. Since NextJS is one of the most popular frameworks built atop React, it made sense to start there.

The path forward was laid out as simply as that. I already liked React, I knew a little about Next and had begun to like that as well, and I was ready for a change from WordPress. A simple, linear path.

Omitted from this intro is why I felt ready for a change from WordPress, so let's start there.

Why not WordPress

After a decade of almost daily use, I know WordPress really well. It's like a very familiar kitchen to me now — I know exactly where everything is when I need it.

And it's not just any old kitchen. WordPress is a kitchen filled with good pans, sharp knives and thick butcher blocks. WordPress is a great kitchen.

Anyone who tells you that WordPress is old or tired, or ill-suited to various use-cases is wrong, uninformed. There has never been any legitimate shame in using it, and there's certainly none in using it today. You might not prefer it's approach, but not much it can't do.

Still, I was ready for a change. Getting WordPress setup with all the conveniences I'm used to is no small feat. I like to start all WordPress projects with 10up's WP Scaffold. It's the 3rd or 4th generation of our WP starting point, and it's been used now on dozens of projects by hundreds of engineers. It's tested, it works, and it's loaded with everything you need for modern development — stylelint, eslint, prettier, Browsersync, etc. It's an excellent tool. But, as a completely bare-bones starting point, it's also a lot to take on.

This bare-bones starting point combined with WP's Block Editor caused me to worry about sluggish momentum. These two starting positions can feel like you're standing at the bottom of two mountains. When you climb the first mountain (WP Scaffold), and get all the theme's base stuff setup — layout, spacing, colours, typography, vertical rhythm, etc — you're immediately presented with your second mountain — styling elements in the Block Editor.

I could have pushed through these hurdles. I push past them every day at work. But maybe the fatigue was setting in — I really didn't want to spend 10-20 hours just setting up basics for my new site. I wanted to have much more accomplished by the 20 hour mark than a solid baseline.


In the past few years I've also grown tired of actually hosting my own sites as well. I host a bunch of pet projects on a VPS Droplet at Digital Ocean. In former times — when I was young, insane, child-less — I used to enjoy setting up PHP / Nginx / MySQL from scratch on a fresh Ubuntu install. I tinker with my server so infrequently now that I forget how it all works every time I want to add a new site. It's a total pain, and no longer an interest of mine.

To sum up, setting up a new WordPress site felt like a burden on multiple fronts. I was worried I'd run out of steam before getting it off the ground in the very limited free time I had available. Reading the tea leaves here a little, a lot of what I'm talking about is this new term I keep hearing — "developer experience" or "dx". Getting an enjoyable dx with WordPress is possible, but it takes some time.

Why NextJS?

And so, enter NextJS.

I've been happily using React for a few years now and have come to enjoy many of the benefits of being in this ecosystem. NextJS is among the biggest of these benefits.

If you've used React but not Next, just imagine that Next takes care of the routing part for you. If you start a new project using create-react-app, you would need to add react-router to your project to handle navigation. You'd need to write a bunch of rules outlining how you go from page to page. With Next, you just put a file in a pages directory and that automatically creates a route for you. So, just having pages/about-us.js would give you an About Us page. Next is a lot more than that, but if you're totally new, that's enough for the moment. It's React with batteries included.

Straight from the NextJS docs: "Next.js aims to have best-in-class developer experience..." with features like the previously mentioned page-based routing, out of the box (Post)CSS support, built-in linting, simple auto-formatting via Prettier, and fast refreshing live server, via Browsersync. NextJS of course also has the obvious and huge benefit of being built atop React. It's React everywhere. React all the way down.

And for all that, the developer experience certainly is good. The linting, auto-formatting, no-config CSS, and live-serving are all essentials for me at this point, and they all work quite well.

Being in the NextJS ecosystem also comes with another truly massive benefit — dead simple hosting via Vercel, the company behind NextJS. When I want to change something, I'm literally just a commit and a push away. When I'm done writing this blog post, for instance, I'll git commit it, merge it into master and push it up. I have this working on my VPS on other sites already via Github webooks, but again, as with all this stuff, I set it up so infrequently, I need to go re-learn it each time from scratch.

But of course we know by now that no technology comes without compromise, and NextJS is no different. This post from Brian Lovin struck many chords with me:

I get stuck in these loops where I redesign the thing once every few years, and am left so thoroughly exhausted and frustrated by the process that I don't want to touch the thing ever again.

Did moving from WordPress to NextJS help in this area, or did I just trade one set of compromises for another? Let's add it up.

The Pros

  1. I like React. Having it everywhere is great.
  2. Javascript is the language I know. If I need to do something custom, I can do it with Javascript instead of futzing around with PHP. Being able to stay in Javascript as a frontend developer is ideal.
  3. Hosting is dead simple, easy and fast.
  4. Deploying code or content is just one commit away.
  5. Next's blank slate is much more ready-to-roll than WordPress' (or rather, WP Scaffold)
  6. As a modern developer, experimenting and keeping up is important. It's hard to fit this experimentation time into a busy workday, so it's nice to have work/side-project overlap.
  7. I like the simplicity and transparency of page-based routing. Need a new page? Create a new file in /pages.
  8. Dedicated React products like Framer Motion are really nice.
  9. I love app-like experiences on the web. They can have downsides, but generally not many for a tiny project like this one.

The cons

  1. Just minutes into this project, I became painfully aware of not having all the things WordPress gives you out of the box. With Next, I've found that there's constant wheel reinvention — simple things like having to format dates, next / previous post navigation, the_loop, an rss feed, a current_menu_item indicator. I'm constantly writing custom code to implement features that WordPress has had for a decade.
  2. Everything feels super brittle. Every time I run npm run watch I grimace a little, wondering what I'm going to face today. I use npm a ton at work, so it's not that I don't have faith in community-contributed packages. There's something about the cutting-edge nature of Next maybe that causes random things to break.
  3. I feel the burden of technical debt (or more aptly, technical overhead) much more acutely. For years, WordPress has just worked. The recent changes to the rapidly-evolving editor aside, WordPress is extremely stable. Updates are completely painless. Letting a WordPress site languish on a VPS for a couple of years is generally no big deal at all. Not so with Next. Let it languish for a few weeks and it feels like you're in for trouble.
  4. Npm packages and WordPress plugins are analogous in that they both give you functionality for free. It's very different functionality though. I liken it to npm giving you a box of legos vs WordPress giving a fully functioning, though not always ideal, toy. This isn't a knock against npm so much as a kudo for the WordPress plugin system. In short, I find it much more likely to find an off-the-shelf plugin to completely solve a problem, while npm packages tend to still need a bunch of assembly. This is good and bad in both directions, of course.
  5. Writing in Markdown just isn’t great. It's fine and it gets the job done. But I don't like it, and I never have. Even with my qualms about the new WP editor, I still far prefer visual text editing. The interface that I write in matters to me, and writing prose in Markdown, in VSCode isn't great.
  6. Using images in Next is extremely frustrating. I've used Next for several months now and they still make almost no sense to me. Manually managing images (as opposed to setting image sizes in WordPress via add_image_size() and having things happen automatically) is also a pain. I don't want to have to care about image sizes and proportions, but yet I have to.

Why not both?

When I set out on this path, I wanted to get away from my VPS, away from WordPress, away from databases and have everything in Git. Everything local, everything static. But of course it's since become painfully obvious that I've just traded one set of constraints for another.

I've traded a burdensome editor for Markdown. I've traded stability for brittleness. I've traded the_permalink for an unusual <Link> component. I've traded a media library for a terribly frustrating <Image>.

When I started down this path, I naively thought that I was only trading up — trading annoyance for ease, complexity for simplicity. I should so obviously have known better. I was just trading one set of compromises for another set.

As I go forward here, I'm reconsidering the possibility of using both WordPress and NextJS together — one as the data store, one as the interaction layer. Something I didn't want to do up until now to keep things "simple".

The benefits seem straightforward enough:

  1. Using WordPress gives me a good, if overly complex, visual editor. It also gives me richer formatting — groups and columns and things that Markdown doesn't natively offer.
  2. Since WordPress is a CMS, I'd have access to a CMS. Any kind of new content formats I dream up could be implemented in WordPress and served to Next via the rest api.
  3. Aaah the rest api. Like the core convenience functions in WordPress (the_loop, the_date, the_permalink, etc), the rest api has a bunch of these convenience paths paved as well. I've spent a ton of time with the rest api over the years and it truly is excellent.

At this moment, I don't know what direction I'll go in. I miss a bunch of conveniences WordPress offers, but I'm also overall happy with what Next and Vercel offer me. I'm glad to have run into all these hurdles with NextJS, as I'm now aware of them and, I think, the better for it. And of course, in the end, this is a personal site. It's whole purpose is to afford space for experimentation.

All that said, if I was to start something new — something that involved anything more than some pages and a blog — I'm pretty sure I'd choose a hybrid approach.

I'd set up WordPress for use headless-ly, render a initial set of data with getStaticProps and lean back on old faithful useEffect() for anything else I need as I go. At least I think I'd do that. I definitely might.

To finish up, I return to Brian Lovin for some parting wisdom:

Spoiler alert: there is no perfect system. Every solution is a hack. Once I accepted this, I could focus on finding the least-hacky setup that would cover 90% of my needs.

Should you move your stuff to NextJS? Yes, I 100% think that you absolutely, maybe should.

Follow along →@saltcod