Migrated My Blog to Astro: Goodbye WordPress!

It’s been a while since my last blog post!
As the title says, I migrated my blog from WordPress to Astro. I’ve been using WordPress and PHP since I was a teenager, and I hadn’t really tried anything else for making blogs. Obviously, I’ve made websites using other tools, but when it came to writing content, I always considered WordPress my first option due to the ease of getting started.
However, I began getting fed up with WordPress and finally took the step of migrating the whole site to Astro. I’ll explain the reasons why I decided to ditch WordPress in a bit.
Interestingly, I’ve been working on the technical side of my blog (creating themes, fixing bugs, etc.) rather than actually writing content, but I hope this changes with the upgrade since the setup is so much nicer now.
First Impressions of Astro
Getting started with Astro was pretty easy, and I didn’t need to read the documentation to know what I was doing. I felt it was easier than Next.js, which I’ve also used in the past and is often considered an alternative to Astro for some use cases.
I’ve only used the vanilla .astro
files, which are a mix of vanilla HTML/CSS/JS, but can be used with some extra data initializations, and can be composed and nested similar to how React components work.
I also liked the fact that you can use any library you want, such as React, Vue, or Svelte, and the components can be inserted into the pages independently of each other. This means you don’t really need to commit to a single library/framework if you haven’t decided yet which one is best for you. This is the islands architecture, which I haven’t really explored so far.
Astro is perfect for my use case, which is to create a static blog with little to no extra functionality. In my previous WordPress setup, I had disabled the comments section, had no dynamically generated content, and while I did have search functionality, that can also probably be implemented with some raw JavaScript and other workarounds with Astro.
Reasons I Ditched WordPress
Here I’ll explain some reasons why I felt like I should stop using WordPress and instead go for something else.
Difficult to Manage Content
Managing content in WordPress is very cumbersome. Sure, it has a nice GUI where you can see all the posts, but I’m more of a terminal person; I like executing commands and automating things. WordPress posts are stored in the database (MariaDB in my case), which means you need an SQL client to access the raw data. This data is really obfuscated since there are many weird columns with strange values. Not only that, but if you want to back up your posts, you need to do a database backup, which comparatively takes more time and effort.
Contrast this with Astro, where the content can be kept as Markdown files in the same repository as the blog. I can easily use tools I’m familiar with, like Git, to check the post editing history. I also implemented a proofreading script in Python which detects some common typing issues, like having a comma without a space afterward. Some of these typing issues can also be corrected with an LLM if you tell it to proofread your stuff, but I like to have my custom script too.
Perhaps the biggest improvement with Astro is that now I can write my blog posts in Neovim. I absolutely hate writing content inside the WordPress GUI; it’s extremely bad. Even with the Markdown editor, it’s just terrible (mainly because it has no Vim motions 😉).
WordPress Source Code and APIs are Terrible
When I first created my WordPress theme, I had to use PHP for the HTML templates and use the provided APIs to do various things like fetching posts and getting previous/next post links, etc. Personally, I hated how the code is organized and how unnatural it feels to use. The resulting code was very brittle, and almost no tooling to lint/format it existed. Astro works mainly with JavaScript, which means the ecosystem is huge, and I’ve been able to catch several bugs and bad code snippets thanks to those tools. With WordPress, even simple things like formatting the HTML were difficult because of the embedded PHP portions, which caused the formatter to not understand the HTML syntax.
Deployment is Too Heavy
WordPress needs a web server (I was using Nginx), a database (MariaDB), a PHP interpreter, and the hosting is probably not going to be free.
Astro generates a static site which can be deployed for free on Netlify or CloudFlare.
This says it all.
Security Concerns in WordPress
Since WordPress dynamically serves the content on every request, and that content is stored in a database on a server, there are several possible points of failure. I’m not talking about the server going down or the database server crashing, which actually never happened. As a matter of fact, I had a situation where my server’s disk ran out of space and many of my Node.js apps crashed, but my WordPress blog was the only thing that continued working properly.
I’m talking about the fact that WordPress has several entry points, such as the login screen, comments, etc., which can be used by a malicious user if you don’t configure it right. If the login password is insecure, someone could exploit that, and if the spam filter isn’t set, someone could write malicious comments. This never happened to me because I disabled comments, had a strong password, and even changed the login URL to a custom one that only I knew.
I would often check my blog to see if someone had broken into my server and changed some content as a joke. Even if that had happened, it would have been difficult to track down since the history changes aren’t easily verifiable, as opposed to when using Git.
With a statically generated site, none of these are things of concern, since a static site can’t have its login screen exploited, be SQL-injected, or have any of those problems.
The Templating Engine is Horrible
Take a look at the following implementation:
<!-- top-partial.php -->
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<!-- bottom-partial.php -->
</body>
</html>
Now let’s put it all together to create a page:
<?php get_template_part('./top-partial') ?>
<span>This is the page content!</span>
<?php get_template_part('./bottom-partial') ?>
Can you see how this can go wrong?
This is the worst way to combine HTML partials/snippets to create web pages. The reason is that there’s no way to verify the top and bottom partials are correct HTML, with their tags correctly closed and proper syntax. The final output in this case is correct HTML with all the tags properly closed, but it’s not easy to know that beforehand with a static analysis tool like a linter or compiler. Eventually, the HTML will become a spaghetti mess, and it’d be impossible to know which tag wasn’t closed properly (nor in what file it is located).
Absolute nightmare.
WordPress allows this type of code without complaining. Other frameworks like Ruby on Rails also allow this kind of templating, but at least you can configure it to use more modern templating engines as well.
A much better approach is what modern frameworks and libraries do, which is to use React-like component composition, where each component is statically checked to verify the syntax is correct. Astro templates follow this approach too.
Things I’ll Miss About WordPress
Will I miss anything about WordPress? Probably not, but it’s worth mentioning that there are a few things that Astro can’t do out of the box (as far as I know).
Here are some examples:
- No comment section: I don’t need it, but if I did, it seems non-trivial to implement at the same level of robustness as the native comment section functionality in WordPress.
- Search functionality: This can be implemented with some JavaScript libraries like Pagefind.
- SEO: I have the impression this is easier on WordPress, at least initially. I could be wrong, though.
At any rate, I have no regrets. Bye, WordPress!