I hit the cutover button at 2 in the morning, coffee going cold, DNS TTL already lowered to 60 seconds. The client did not know we were doing this tonight. If it worked, they would wake up to a faster site. If it did not, I had 40 minutes to roll back before the first European visitors started hitting the homepage. That is the moment I want to start this story, because everything I am about to tell you was decided in the weeks before that single click.
The site was a real one. A mid-sized WordPress install I have maintained for a client for about four years. Around 500 posts, 4 custom post types (case studies, team members, services, locations), a few hundred media items, and the usual archaeological layer of plugins that nobody remembers installing. I wanted to migrate it to Squilla not as a toy experiment but as a stress test. If Squilla could not handle a normal client site, then it was not ready, and I needed to know.
What worked
The piece I am proudest of is the export pipeline. I ran WP-CLI to dump posts, postmeta, terms, and media references as JSON, then piped that JSON through a Tengo script that mapped WordPress fields to Squilla node fields. Title to title, content to a single ek-post-body block, postmeta keys to node fields_data, taxonomies to Squilla taxonomies. The whole mapping lived in one readable file. When I found a mistake, I fixed it and re-ran the import. No clicking through admin screens. No CSV exports opened in Excel.
Media imported in batches via core.media.import_url. I gave the script the old media URLs from the WordPress JSON, it pulled each file, ran it through the media-manager extension, generated WebP variants, and returned new Squilla media IDs. Then a second pass walked the post HTML and rewrote the old image src attributes to point at the new Squilla URLs. About 380 media items moved in under 10 minutes.
Redirects were the nicest surprise. Because I had both the old WordPress permalink and the new Squilla slug for every node, I auto-generated a redirects file at the end of the import. The redirect extension picked it up, and from the moment the new site went live, every old Google result kept working. I did not lose a single inbound link.
What hurt
Shortcodes. So many shortcodes. About 80 posts used shortcode-heavy layouts from a page builder the client had used three years ago, and the shortcodes did not unwrap into anything sane. I ended up converting those by hand into Squilla blocks. It took an evening. If I had a do-over, I would write a small parser for the two or three shortcode patterns that covered 90 percent of the posts, and only hand-convert the long tail.
Two plugins had their own custom tables that did not map to anything in Squilla. One was a reviews plugin, the other was a custom event calendar. There was no clean import path, so I had to write two small Squilla extensions, each with its own table, its own admin UI, and its own migration script that read the old MySQL rows and inserted Squilla rows. That was the bulk of the 6 hours of scripting work, and honestly the extensions are better than what the plugins offered, but it was real work I had not budgeted for.
SEO meta was the last sharp edge. The site used Yoast, and Yoast stores its meta in postmeta with nested serialized PHP arrays for things like Open Graph overrides, focus keywords, and breadcrumb settings. I had to write a tiny PHP unserializer in Go to read those fields cleanly, then map them onto Squilla's seo_settings. Once that parser worked, every post had its meta title, description, and canonical URL preserved. But I lost about an hour to a single bug where a serialized array contained a UTF-8 byte that broke my length prefix math.
The numbers
Roughly 6 hours of scripting spread over three evenings. Around 40 minutes of actual import runtime on the night of cutover. 12 manual fixes after the import, mostly shortcode posts and a handful of broken internal links. Zero data loss. Zero downtime longer than the DNS TTL.
The verdict
A clean modern WordPress site migrates to Squilla really well. If your content is mostly in the post content field, your media is in the standard library, and you use Yoast or RankMath for SEO, you can be on Squilla in a weekend.
A 10-year-old WordPress site does not migrate well, and that is not WordPress's fault. WordPress is a 21-year-old codebase carrying everyone's plugin history. Every shortcode, every custom table, every serialized blob is someone else's decision from years ago that you now have to interpret. Migration is hard not because of WordPress, but because of WordPress's plugins. The cleaner the site you start from, the less of your own code you have to write to get out.
The client woke up. The site was faster. They never noticed the cutover happened. That is the only review I needed.