Tech 24 min read

Cloudflare's serverless CMS EmDash is now in beta as a WordPress successor

IkesanContents

WordPress is now 24 years old. It powers more than 40% of the internet, but its plugin security problems have only gotten worse. Cloudflare’s beta release on April 2, EmDash, tries to solve that structural problem by rethinking the architecture itself. It is a full-stack serverless CMS built on Astro 6.0, and it is open source under the MIT license.

It is called a “WordPress successor,” but that is only partly fair. WordPress has 24 years of ecosystem depth, while EmDash is still at v0.1.0. On the other hand, there are areas where WordPress simply cannot fix its own structural problems and EmDash is starting from a clean design. I looked at the strengths and weaknesses side by side.

Overall Comparison

DimensionWordPressEmDashAdvantage
LanguagePHPTypeScriptDepends
Theme engineCustom template system (PHP)Astro 6.0Depends
Data storeMySQL / MariaDBD1 (SQLite-compatible)WordPress (proven)
HostingAnywhere, even cheap shared hostingCloudflare Workers or any environment that runs workerdWordPress (more options)
Plugins59,000+Ecosystem still startingWordPress (huge lead)
Themes12,000+ in the official directoryA few official themes so farWordPress (huge lead)
Plugin isolationNone. Full accessFully isolated in V8 isolatesEmDash (structural win)
Admin UIMature and usable for non-engineersBasic, still evolvingWordPress (maturity)
CommunityHuge. Lots of Japanese resources tooStarting from zeroWordPress (huge lead)
LicenseGPLv2MITEmDash (freedom)
Initial costFree to a few hundred yen per monthRuns on Cloudflare’s free tierTie
ScalabilityNeeds extra servers or CDN layersRuns at the edge and auto-scalesEmDash
AuthenticationPasswords, with 2FA via pluginsPasskeys by defaultEmDash
Content monetizationPlugins like WooCommercex402 built inEmDash (simpler)
AI agent integrationREST API as an add-onMCP server built inEmDash
Multilingual supportPlugins like WPML and PolylangAstro i18n + edge routing built inDepends

The things EmDash wins on are architectural. WordPress cannot easily catch up there. The things WordPress wins on are ecosystem depth and operational maturity, and EmDash will need years to narrow that gap.

Where EmDash Wins Structurally

WordPress Plugin Security Problems

WordPress plugins get full access to the site’s database and filesystem the moment they are installed. There is no sandbox and no meaningful privilege separation. Through add_action and add_filter, a plugin can hook into anything in WordPress, and through $wpdb it can run raw SQL. In practice, installing a plugin has long been close to giving a stranger root on the server.

graph LR
    subgraph WordPress plugin model
        P[Plugin] -->|add_action/add_filter| H[All hooks]
        P -->|$wpdb| DB[(MySQL)]
        P -->|file_get_contents etc.| FS[Filesystem]
        P -->|wp_remote_get etc.| NET[External network]
    end

The damage is visible in the numbers.

MetricValue
New vulnerabilities in the WordPress ecosystem in 202510,794 (about 30 per day)
Share caused by plugins96%
Vulnerabilities exploitable without authenticationMore than 43%
High-severity vulnerabilities in 2025More than the previous two years combined
Developers who did not fix bugs even after learning about them52%

According to Patchstack’s report, the 2026 CVE total is expected to rise another 15% year over year to about 55,000. More than 800 plugins are waiting in the WordPress.org review queue, and processing takes at least two weeks.

That does not mean WordPress is uniquely dangerous. If you have 59,000 plugins, you should expect a lot of vulnerabilities. The real problem is the architecture: one vulnerable plugin can endanger the whole site. WordPress cannot easily fix that after the fact, because running plugins in the same PHP process is part of the platform’s core design.

EmDash runs each plugin as an isolated Dynamic Worker inside its own V8 isolate.

What Is a V8 Isolate?

V8 is the JavaScript engine used by Chrome and Node.js. An isolate is an independent execution environment inside V8. Each isolate has its own heap and cannot access the memory of another isolate. Unlike container virtualization, this has almost no OS-level overhead, so startup happens in milliseconds. Cloudflare says it is 100x faster than containers.

Comparing the Isolation Model

AspectWordPressEmDash
Plugin execution environmentSame PHP processSeparate V8 isolate per plugin
Memory spaceSharedFully isolated
DB accessRaw SQL through $wpdbAPI only. No raw SQL
FilesystemFull accessNo access
NetworkUnrestrictedNo network unless the host is explicitly allowed
Permission modelFull delegation (install = full access)Capability-based (only declared permissions)
Blast radius of a vulnerable pluginWhole site: DB, files, and other pluginsOnly the permissions granted to that plugin

In WordPress, one compromised plugin can expose the entire site, the database, the filesystem, and even other sites on the same server. In EmDash, the damage is supposed to stop at the permissions the plugin was granted.

Cloudflare Workers adds multiple layers of defense:

LayerProtection
V8 isolateComplete memory isolation
Process sandboxLinux namespaces + seccomp to block filesystem and network access
Cordon separationSeparate process groups by trust level; free-tier and enterprise workloads do not share a group
Hardware protectionRandom memory protection keys protect heap data; even with a bug, 92% of cases trap at the hardware layer
Timing-attack protectionDate.now() is fixed while code runs, and there is no multithreading, so side-channel attacks are structurally limited

WordPress cannot bolt this on after the fact. PHP’s process model does not allow this sort of plugin isolation. A WAF or malware scanner can help from the outside, but it cannot stop a plugin from misbehaving internally.

Capability-Based Access Control

EmDash plugins only receive the capabilities declared in their manifest. There is no direct database or filesystem access.

import { definePlugin } from "emdash";

export default () => definePlugin({
  id: "notify-on-publish",
  version: "1.0.0",
  capabilities: ["read:content", "email:send"],
  hooks: {
    "content:afterSave": async (event, ctx) => {
      // ctx only has the read:content and email:send capabilities
      // No direct DB access or raw network access is possible
    }
  }
});

WordPress has no way to tell users what a plugin can do at install time. Unlike an Android app that asks for permissions up front, a WordPress plugin silently takes everything. EmDash’s model is closer to Android permissions: users can see what they are allowing.

That said, capability-based access has limits. A plugin with read:content can still read everything in that scope. Whether EmDash can eventually support finer-grained controls like “only this article” or “only this field” is still unclear from the beta docs.

graph LR
    subgraph WordPress
        WP_Plugin[Plugin] -->|Full access| WP_DB[(Database)]
        WP_Plugin -->|Full access| WP_FS[Filesystem]
        WP_Plugin -->|Unrestricted| WP_Net[External network]
    end
    subgraph EmDash
        ED_Plugin[Plugin<br/>Dynamic Worker] -->|read:content only| ED_DB[(D1)]
        ED_Plugin -->|email:send only| ED_Email[Mail API]
        ED_Plugin -.-x|No access| ED_FS[Filesystem]
        ED_Plugin -.-x|No access| ED_Net[External network]
    end

Performance and Scalability

WordPress is the classic PHP + MySQL server-side stack. Every request generates the full HTML page on the server and sends queries to MySQL. To speed that up, you usually need page-cache plugins, a CDN, and sometimes Varnish or Redis at the infrastructure layer.

EmDash runs on Cloudflare Workers, so requests are processed at the edge, close to the user. There is no need to build a separate CDN or cache layer. D1 is also at the edge, so database latency stays low.

graph TD
    A[Browser] -->|Request| B[Cloudflare Workers<br/>EmDash core]
    B --> C[Astro 6.0<br/>Theme engine]
    B --> D[D1<br/>SQLite-compatible DB]
    B --> E[R2<br/>Media storage]
    B -->|capability binding| F[Dynamic Worker<br/>Plugin A]
    B -->|capability binding| G[Dynamic Worker<br/>Plugin B]
    F -.->|Only allowed actions| D
    G -.->|Only allowed actions| E
AspectWordPressEmDash
RuntimeOrigin serverEdge (300+ locations worldwide)
Scaling upAdd servers and load balancersAutomatic via Workers
Scaling downServers keep runningZero traffic, zero cost
CachingBuilt with plugins + CDNEdge cache is standard
DB accessTCP to MySQL from the originLocal access to D1 from the edge
Cold startPHP process startup (hundreds of ms)V8 isolate startup (milliseconds)

WordPress often falls over when traffic spikes. 503s during a viral event are normal, and fixing them usually requires an infrastructure engineer. EmDash should be structurally more resilient as long as it stays on Cloudflare’s platform.

That said, WordPress performance can already be good enough for many sites if you use the right plugins. WP Rocket and Cloudflare APO can get you close to static-site speeds. Whether this is enough motivation to switch depends on the site.

Default Authentication Is Much Stronger

AspectWordPressEmDash
Default authPasswordPasskey (passwordless)
2FAAdded via pluginNot needed; the passkey already covers MFA
SSO integrationVia plugins (SAML/OIDC/LDAP)Via plugins, with automatic IdP metadata provisioning
Password DBExists (bcrypt hashes)Does not exist

EmDash does not store passwords at all. If there is no password database, password stuffing and brute-force attacks do not apply. WordPress defaults to password auth, and 2FA is up to the site owner. Both systems have the same four roles: administrator, editor, author, and contributor.

WordPress authentication plugins are mature, though. miniOrange, WP SAML Auth, and similar tools can build enterprise-grade SSO setups with Active Directory or LDAP integration.

How It Works Without a Password DB

To be precise, EmDash is not storing nothing at all. Passkeys (FIDO2 / WebAuthn) use public-key cryptography, so the server stores a public key instead of a password hash.

The registration flow looks like this:

  1. The server generates a random challenge and sends it to the browser
  2. The browser asks the authenticator to generate a key pair
  3. The user confirms with biometrics or a PIN
  4. The authenticator generates a secret/public key pair and keeps the secret key on the device
  5. The browser sends the public key and credential ID back to the server, which stores only those values

At login, the server sends a challenge, the device signs it with the secret key, and the server verifies the signature with the stored public key. No password ever travels across the wire.

sequenceDiagram
    participant U as User
    participant B as Browser
    participant A as Authenticator<br/>(security chip)
    participant S as EmDash server

    Note over U,S: Registration flow
    B->>S: Registration request
    S->>B: Challenge + server data
    B->>A: Request key-pair generation
    U->>A: Biometric or PIN
    A->>A: Generate secret/public key pair
    A->>B: Public key + credential ID + signature
    B->>S: Public key + credential ID + signature
    S->>S: Save public key (no password stored)

    Note over U,S: Login flow
    B->>S: Login request
    S->>B: Challenge + credential ID
    B->>A: Request signature
    U->>A: Biometric or PIN
    A->>A: Sign the challenge with the secret key
    A->>B: Signature data
    B->>S: Signature data
    S->>S: Verify signature with the stored public key

The important point is that leaking the public key is harmless. You cannot derive the secret key from it. That is a very different risk profile from a leaked password database.

If leakedPassword DBPasskey public-key DB
Offline brute-forcePossible; weak passwords fall quicklyNot possible; public key does not reveal the secret
Credential stuffingPossible if passwords are reusedNot possible; each key pair is unique per site
PhishingWorks if the user enters the password on a fake siteDoes not work; the authenticator checks the origin and will not sign for a fake site
Response after DB leakForce every user to reset passwordsNo action needed; the public key alone is useless

Passkeys count as MFA because they combine device possession with biometrics or a PIN. One step gives you two factors, so there is no need to bolt on a separate 2FA plugin like you do in WordPress.

Content Monetization

EmDash supports x402, a proposed “internet-native payment standard,” out of the box. Set a price and wallet address on the content and you can charge per article with very little engineering work, at least according to Cloudflare.

Doing the same thing in WordPress usually means combining WooCommerce and MemberPress. You have to set up the payment provider contract, Stripe, webhooks, and a membership plugin, and getting it all working can take days or weeks. Plugin compatibility issues are common too.

WordPress does have a much richer e-commerce ecosystem, though. Monthly subscriptions, usage-based billing, coupons, affiliate programs, and integration with physical products are all well covered. x402 is good for per-article charging, but it may not handle more complex sales flows.

AI Agent Integration

Every EmDash instance includes a Model Context Protocol (MCP) server. Through the EmDash CLI, you can upload media, search content, and manage schemas programmatically, so the whole system is designed with AI agents in mind.

There are also Agent Skills for plugin creation and theme migration. For example, the “Block Kit Agent Skill” can convert WordPress blocks into EmDash format.

WordPress has a REST API too, but it was added later and often comes with authentication setup pain and plugin conflicts. A built-in MCP server is a clear advantage if you care about AI-agent compatibility in 2026.

Theme Development: PHP vs Astro

An EmDash theme is itself an Astro project: Pages, Layouts, Components, Styles, and Seed files that define content types and fields. Themes do not get database privileges either. They fetch content through EmDash’s API and never need raw SQL. By removing direct DB access from both plugins and themes, EmDash structurally eliminates the SQL-injection attack surface.

WordPress themes are PHP files, which means a theme can call $wpdb->query() or make external requests with file_get_contents(). Malicious themes have been discovered in the WordPress.org theme directory more than once. EmDash simply does not have this attack path.

AspectWordPress themeEmDash theme
LanguagePHP (template tags)Astro + TypeScript
CustomizationTheme customizer (GUI)Code editing (CLI / editor)
Theme store12,000+ (free and paid)A few official themes so far
DB operationsPossible, including raw SQLNot possible; API only
Security riskMalware can arrive through themesNo direct attack surface
Learning curveBasic PHP is enoughYou need front-end development knowledge
No-code supportTheme customizer, GutenbergNone

For developers, Astro + TypeScript is modern and pleasant. For non-engineers, WordPress’s theme customizer and Gutenberg are much more approachable. That difference is about user audience, not technical merit.

Where WordPress Clearly Wins

Ecosystem Depth

With more than 59,000 plugins and 12,000 themes, there is usually already a plugin for whatever you want to do. WooCommerce for e-commerce, Yoast SEO for search, Contact Form 7 for forms, UpdraftPlus for backups. Each plugin has its own developer community, documentation, and tutorials.

EmDash’s ecosystem is starting from zero. SEO plugins, form builders, backup tools, and payment integrations are still missing or need to be built manually.

Non-Engineer Usability

Over 20 years, WordPress has become a CMS that non-engineers can actually operate. The admin screen works entirely in the browser, and posts, images, theme changes, and plugin installs are all GUI-driven. Gutenberg’s block-based editing is close to a Notion-like experience.

EmDash’s admin UI is still minimal and clearly aimed at engineers. Theme customization requires code, and plugin development assumes TypeScript knowledge. For someone who just wants to write blog posts, EmDash is still too technical.

Hosting Flexibility

WordPress runs everywhere, from cheap shared hosting to enterprise setups on AWS. In Japan, providers like Sakura Internet, Xserver, and Lolipop all support one-click WordPress installs. You can host it yourself or move it to the cloud, and migration procedures are well understood.

EmDash is really optimized for Cloudflare Workers. It is said to run elsewhere with workerd, the open-source Workers runtime, but real self-hosting examples are rare. In practice, that means you are much more dependent on Cloudflare’s service and pricing than you are with WordPress.

Information and Community

If you get stuck with WordPress, a search usually finds a Japanese solution right away. There is Stack Overflow, Qiita, Zenn, and countless blogs. There are also lots of Japanese books. Hiring WordPress developers is easy because PHP and WordPress experience is common worldwide.

With EmDash, you mostly have the official docs and GitHub issues. Japanese information is effectively nonexistent. Hiring is also hard because “EmDash experience” does not really exist yet.

Existing Assets and Workflows

There are already hundreds of millions of WordPress sites, each with their own custom themes, plugin settings, and operational workflows. Even if migration tools exist, the workflow rewrite cost can be bigger than the technical migration cost.

WooCommerce shops, bbPress forums, and LearnDash course sites are especially hard to move because so much depends on plugins. EmDash will need years to match that breadth.

Migration From WordPress

EmDash offers two migration paths: export a WXR file from WordPress and import it, or install the EmDash Exporter plugin and migrate through a secure endpoint. The latter is protected by WordPress application passwords and can also move media files automatically. Cloudflare claims the migration takes only a few minutes.

Custom post types become EmDash Collections. For WordPress theme migration, there is an Agent Skill called wordpress-theme-to-emdash.

Content migration is relatively easy; reproducing the look and feel of the theme and replacing plugin functionality is the real bottleneck. A simple blog might move in minutes, but a site with 10 or more plugins could take weeks.

What the v0.1.0 Beta Includes

The current release is a v0.1.0 preview beta. You can set it up instantly with npm create emdash@latest, and there is a one-click deploy button for Cloudflare. If you just want to try the admin screen, there is a Playground at emdashcms.com. The GitHub repo is emdash-cms/emdash, and the project is MIT licensed.

Cloudflare has been shipping platform pieces for Workers very quickly over the last few months: VoidZero’s Vite-native deploy platform, Vinext’s reimplementation of Next.js, and a real-time analytics stack on Workers. EmDash is part of that same wave.

I also covered the threat of third-party scripts in Cloudflare’s Client-Side Security GNN+LLM detection. EmDash tries to solve the problem at the root by making plugins incapable of doing evil in the first place.

Multilingual Support

Modern websites need multilingual support more often than before. Cross-border e-commerce, global corporate sites, and even personal blogs now often ship with English versions. WordPress and EmDash take very different approaches.

WordPress Multilingual Support

WordPress itself has no multilingual feature. You need plugins like WPML, Polylang, or TranslatePress.

PluginApproachPriceNotes
WPMLDuplicate posts by languagePaid ($39+/year)The most common choice; strong WooCommerce integration
PolylangDuplicate posts by languageFree version availableLighter than WPML; easy to start with
TranslatePressEdit translations from the front endFree version availableLets you see the page while translating
MultilingualPressSplit each language into a separate multisitePaidEnterprise-oriented; strong site isolation

WPML and Polylang duplicate the post per language, so the Japanese and English versions are stored as separate posts. That doubles or triples the post count, and the setup gets messy fast: language switchers, hreflang output, and URL structure all have to be configured carefully.

Multilingual plugins also tend to create compatibility issues with other plugins. A cache plugin may fail to cache language-specific pages, an SEO plugin may output the wrong hreflang tags, and e-commerce plugins may lose fields during translation. The combinations explode, and troubleshooting takes time.

That said, these plugins are mature. They provide translation memory, translator role management, translation progress tracking, and integrations with external translation services like DeepL and Google Translate. Large multilingual workflows already know how to use them.

EmDash Multilingual Support

EmDash is built on Astro 6.0’s built-in i18n routing. Astro supports language-based routing at the framework level, so multilingual support is not bolted on later.

// astro.config.ts (EmDash theme-side configuration)
export default defineConfig({
  i18n: {
    defaultLocale: "ja",
    locales: ["ja", "en", "zh-hans", "ko"],
    routing: {
      prefixDefaultLocale: false
      // ja: /articles/slug
      // en: /en/articles/slug
    }
  }
});

The edge location matters because Cloudflare Workers can handle locale detection and content routing before the request ever reaches an origin.

graph TD
    A[Browser] -->|Request| B[Cloudflare Workers<br/>Edge location]
    B -->|Accept-Language<br/>CF-IPCountry| C{Detect locale}
    C -->|ja| D[Japanese content]
    C -->|en| E[English content]
    C -->|zh-hans| F[Chinese content]
    D --> G[Fetch from D1<br/>edge cache]
    E --> G
    F --> G

WordPress multilingual plugins do locale detection on the origin server and fetch the relevant language from MySQL. EmDash does it at the edge, so the language-detection-to-redirect-to-content chain is structurally lower latency.

In the D1 content schema, translations are managed as fields on a Collection. Unlike WordPress, which duplicates the post by language, EmDash keeps it as one content entry with multiple language fields.

AspectWordPressEmDash
Multilingual implementationPlugin (added later)Built into the framework
Content structureOne post per languageOne entry with multiple language fields
URL structureDepends on plugin settingsAstro i18n routing
Locale detectionOn the origin serverAt the edge
hreflang tagsOutput by the pluginGenerated by the framework
Translation managementTranslation memory, progress tracking, translator rolesBasic field management
Machine translation integrationDeepL, Google Translate pluginsPossible via API, but no official integration yet
RTL supportPossible via pluginsSupported via Astro’s dir attribute
MaturityMillions of sites already use itBeta stage

The architectural advantage is clear, but WordPress is still far ahead in translation workflows. Translation memory, translator roles, progress tracking, agency collaboration - those are still missing in EmDash.

For a personal blog or a small site, EmDash’s built-in approach is simpler. For a 50-language enterprise site or a large translation team, WordPress still has the workflow support you need.

URL Structure and Routing

If you use a CMS in production, URL structure and redirects are never optional. SEO often wants categories in the URL, redirects need fine control, and subdirectory installs need careful handling. WordPress has always been strong here because you can freely tweak it in functions.php.

WordPress URL Control

You can change permalinks through the admin UI, but serious customization usually means working with the Rewrite API in functions.php.

// functions.php: make a custom post type use /news/slug/
function custom_news_rewrite() {
    add_rewrite_rule(
        '^news/([^/]+)/?$',
        'index.php?post_type=news&name=$matches[1]',
        'top'
    );
}
add_action('init', 'custom_news_rewrite');

// Change the permalink structure to /%category%/%postname%/
function custom_permalink_structure() {
    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure('/%category%/%postname%/');
}

You can add redirect rules in .htaccess (Apache) or nginx.conf, register custom query variables with add_rewrite_tag, and conditionally redirect from template_redirect. In other words, PHP can do almost anything. And because 20 years of Stack Overflow answers exist, you can usually find the code snippet you need.

EmDash URL Control

EmDash is Astro 6.0-based, so routing follows Astro’s conventions. Astro uses file-based routing, where the structure under src/pages/ becomes the URL. It is written in TypeScript.

src/pages/
├── index.astro          → /
├── about.astro          → /about
├── articles/
│   └── [slug].astro     → /articles/any-slug
└── [lang]/
    └── articles/
        └── [slug].astro → /en/articles/any-slug

Dynamic routes are handled with [slug].astro or [...path].astro, and getStaticPaths() controls what gets generated. Category-based URLs are easy to express.

// src/pages/[category]/[slug].astro
export async function getStaticPaths() {
  const posts = await getCollection("posts");
  return posts.map((post) => ({
    params: {
      category: post.data.category,
      slug: post.slug,
    },
    props: { post },
  }));
}
// → /tech/my-article, /diary/my-diary, etc.

Redirects are declared in astro.config.ts.

// astro.config.ts
export default defineConfig({
  redirects: {
    "/old-path": "/new-path",
    "/blog/[...slug]": "/articles/[...slug]",
  },
});

Astro file-based routing plus astro.config.ts plus middleware gives you the same kind of flexibility as WordPress’s functions.php + Rewrite API. Middleware lets you write pre-processing steps like auth checks, redirects, and header manipulation in TypeScript.

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

export const onRequest = defineMiddleware(async (context, next) => {
  const url = new URL(context.request.url);
  
  // Redirect /old-blog/* to /articles/*
  if (url.pathname.startsWith("/old-blog/")) {
    const newPath = url.pathname.replace("/old-blog/", "/articles/");
    return context.redirect(newPath, 301);
  }
  
  return next();
});

URL Control Comparison

AspectWordPressEmDash (Astro)
Permalink setupGUI + functions.phpastro.config.ts + file structure
Dynamic routingRewrite API (regex)[slug].astro (file-based)
Redirects.htaccess / functions.phpastro.config.ts / middleware
MiddlewareHook system (actions / filters)src/middleware.ts (TypeScript)
Subdirectory deploymentsite_url / home_urlbase option
Custom query varsadd_rewrite_tagURL params / Astro.url.searchParams
LanguagePHPTypeScript
Available knowledgeHuge (20 years of examples)Mostly Astro docs

The answer to “Can you write routing in TypeScript?” is yes. Astro’s file-based routing is more intuitive than WordPress’s Rewrite API and much less likely to turn into regex hell. The middleware model is also easier to follow than functions.php hooks.

That said, how freely EmDash can route inside Cloudflare Workers is a separate question. Astro alone can do almost anything, but EmDash prioritizes plugin and theme sandboxing. Some routing constraints may still exist on the theme side, and the beta docs are still thin.

WordPress’s Rewrite API is powerful, but internally every rule gets stored in wp_options as rewrite_rules, and matching happens on every request. That can hurt performance as the rule set grows. EmDash’s file-based routing is resolved at build time, so there is no runtime overhead.

WordPress’s 24 Years

I mentioned “24 years” at the top, but it is worth looking at what that actually means.

In 2003, 19-year-old Matt Mullenweg and Mike Little forked b2/cafelog, a PHP blogging tool, and turned it into WordPress. It started as a small blogging tool.

YearVersionEvent
20030.70Forked from b2/cafelog and was born
20041.2Plugin API introduced. The ecosystem begins
20051.5Theme system introduced. Automattic founded the same year
20052.0WYSIWYG editor added
20082.5Major admin redesign
20103.0Custom post types added. A turning point from “blog” to “CMS”
2011WooCommerce appears and WordPress becomes an e-commerce platform too
20154.4REST API integrated into core
20185.0Gutenberg block editor lands, splitting the community
20246.xMullenweg vs WP Engine dispute. Governance issues surface
20266.8+More than 40% of the web, with more than 10,000 vulnerability reports a year

The 2010 WordPress 3.0 release was the real turning point. Custom post types made WordPress useful for more than blogs: e-commerce, corporate sites, portfolios, and real-estate sites. The next year WooCommerce arrived, and WordPress became a serious commerce platform.

The 2018 Gutenberg rollout was the most controversial change. The forced move from the classic editor to block-based editing drew a huge backlash, and the Classic Editor plugin surpassed 5 million installs. It is still used today.

In 2024, WordPress founder Mullenweg publicly criticized WP Engine and temporarily cut off access to WP Engine-related plugins from WordPress.org. That turned into a broader community debate about open-source governance versus commercial use.

The 24-year ecosystem is also carrying technical debt. The PHP process model creates structural security problems, exactly as described above. But on top of that debt sit 59,000 plugins, 12,000 themes, millions of developers, and countless businesses. What EmDash is trying to challenge is not just a product, but all of that accumulated weight.


Because this blog itself is built with Astro, I was curious the moment I saw that EmDash is built on Astro 6.0. The plugin sandbox design is coherent and offers a convincing answer to a problem WordPress has carried for 20 years. Whether v0.1.0 is actually ready for real use is another question, but I do want to try it.