How to Get off WordPress
10. Appendix
Tool alternatives, cost considerations, security comparison, scripts, and migration pitfalls.
Tool alternatives
| Capability | Primary recommendation | Common alternatives |
|---|---|---|
| Frontend | Next.js | Astro, Remix, SvelteKit |
| CMS | Payload | Sanity, Contentful, Strapi |
| Database | Neon Postgres | Supabase, RDS, PlanetScale |
| Media | Backblaze B2 | S3, Cloudflare R2 |
| Brevo | Resend, Postmark, SendGrid | |
| Search | DB native first | Meilisearch, Algolia |
Cost breakdown model
Estimate monthly cost by bucket:
- Frontend hosting and edge bandwidth
- CMS hosting and database
- Media storage and egress
- Email sends and API usage
- Monitoring and alerting tools
Track both steady-state cost and migration-period overlap cost.
Security model comparison
WordPress-heavy model
- Security posture depends on plugin chain quality
- Larger update blast radius in shared runtime
- Frequent emergency patch cadence
Modern decomposed model
- Smaller component-level blast radius
- Explicit service-level access controls
- Easier targeted patching and incident containment
Example migration scripts
Slug normalization
export const normalizeSlug = (value: string) =>
value
.toLowerCase()
.trim()
.replace(/[^a-z0-9\s-]/g, "")
.replace(/\s+/g, "-")
.replace(/-+/g, "-");
Shortcode strip pass
This is a deliberately naive first pass. It can remove text that is not a shortcode, and it will not handle nested or complex shortcode patterns correctly. Use it only as a temporary cleanup step, and expect manual review.
export const stripShortcodes = (html: string) =>
html.replace(/\[[^\]]+\]/g, "");
Common pitfalls
- Underestimating data cleanup effort
- Migrating plugin behavior without business validation
- Launching with incomplete redirect coverage
- Ignoring editor training for the new content model
- Treating migration as a one-time event instead of a new operating model