EmDash CMS vs WordPress: Which One Should You Choose?

EmDash CMS vs WordPress: Which One Should You Choose?

WordPress and EmDash share more DNA than you'd expect for platforms built two decades apart: content types, an admin panel, plugins, themes, media management. The difference is almost entirely in how those pieces work underneath, and that difference is worth understanding before you pick one for your next project.

Table of Contents
  1. Quick Answer
  2. Market Position
  3. Content Model: Raw HTML vs. Structured Data
  4. Plugin Security: The Biggest Structural Gap
  5. Front End: PHP Templates vs. Astro
  6. AI-Native Design
  7. Where WordPress Still Wins
  8. Where EmDash Wins
  9. The Bottom Line

Quick Answer

WordPress is the safer default if you need the largest possible plugin/theme ecosystem, hands-off managed hosting, or a team already fluent in it. EmDash is the better fit if you want structured, API-ready content, a modern Astro-based front end, and plugin security that doesn't rely entirely on trusting third-party code with unrestricted database access.

Market Position

There's no getting around the scale gap: WordPress powers roughly 42% of all websites and holds nearly 60% of the CMS market, even after its first sustained decline in 20-plus years. EmDash, by contrast, is a genuinely new open-source CMS — built by Cloudflare on Astro and positioned explicitly as a "spiritual successor to WordPress" rather than a direct clone. If ecosystem size and hiring pool are your top priority, that gap matters and won't close overnight.

Read also:

Content Model: Raw HTML vs. Structured Data

This is the most consequential technical difference. WordPress stores post content as an HTML string in a single generic table (wp_posts), which is flexible but makes content hard to query, restructure, or feed into anything other than WordPress's own template renderer. EmDash stores content as structured JSON ("portable text"), with each custom content type getting its own dedicated database table with typed columns. In practice, that means EmDash content is inherently easier to reuse across channels, migrate, or hand to an AI agent to restructure — where doing the same thing in WordPress usually means writing custom parsing logic against raw HTML.

Plugin Security: The Biggest Structural Gap

WordPress's plugin ecosystem is both its greatest strength and its most persistent liability. WordPress accounted for the large majority of CMS-related vulnerability disclosures in the past year, and the overwhelming majority of those originated in plugins rather than WordPress core — a natural consequence of plugins having direct, unrestricted access to the site's database and filesystem once installed.

EmDash addresses this at the architecture level: plugins run inside sandboxed, isolated worker environments and must explicitly declare what permissions they need — similar to how modern OAuth scopes work — rather than getting blanket access by default. It's a meaningfully different security posture, though it comes with the tradeoff of a much smaller current plugin catalog than WordPress's 60,000-plus.

Front End: PHP Templates vs. Astro

WordPress themes run on PHP, with the often-unwieldy functions.php as the default extension point — a pattern that's aged along with PHP itself. EmDash's front end runs on Astro, so teams already comfortable with modern JavaScript/TypeScript tooling will feel more at home, and the architecture avoids the kind of unrestricted, catch-all theme execution that's made WordPress themes a security concern in their own right, alongside plugins.

AI-Native Design

This is where EmDash diverges from WordPress most sharply, and from most other CMS platforms generally. Every EmDash installation ships with a built-in Model Context Protocol (MCP) server, letting AI tools create content types, manage entries, configure plugins, and handle deployment programmatically — without a one-off migration script. WordPress has no equivalent built in; AI integrations there are typically bolted on through third-party plugins reading and writing the same unrestricted database access every other plugin has.

Where WordPress Still Wins

  • Plugin and theme selection — there's simply no competing with 60,000+ extensions covering nearly every use case imaginable.
  • Managed hosting options — from $5/month shared hosting to fully managed enterprise platforms, at every price point.
  • Hiring and community support — WordPress developers, agencies, and documentation are everywhere.
  • Maturity — two decades of edge cases already solved, for better or worse.

Where EmDash Wins

  • Structured, API-first content that's genuinely portable across channels, not locked into HTML rendered by one template engine.
  • A fundamentally smaller attack surface from sandboxed, permission-scoped plugins instead of unrestricted plugin access.
  • Built-in AI-native tooling (MCP server, structured CLI output) rather than third-party bolt-ons.
  • A modern Astro front end for teams already working in that ecosystem.

The Bottom Line

If you're choosing based purely on ecosystem maturity and plugin availability today, WordPress remains the safer, better-resourced choice. If you're starting a new project and structured content, plugin security, and AI-native workflows matter more to you than plugin count, EmDash is worth serious evaluation — particularly if you're already comparing it against other headless and API-first platforms rather than treating WordPress as the only baseline.

Share

Comments

Write a comment

Related Articles

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

July 16, 2026

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

July 16, 2026

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

July 16, 2026

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

TL;DR — A custom session-cookie login flow appeared to succeed on localhost (the OTP verified, the response looked fine) but every subsequent request to a login-gated page treated the visitor as logged out. Identical code worked fine on the live HTTPS site. The cookie's Secure attribute was hardcoded to true — and per the cookie spec, browsers never store or send a Secure cookie over a plain, non-HTTPS connection.

Table of Contents
  1. Diagnostic
  2. Root cause
  3. Fix
  4. Lessons learned

Diagnostic

Check the actual Set-Cookie response header and the browser's own cookie storage panel — on localhost over http://, the cookie is sent by the server but never actually stored by the browser.

Root cause

// before -- assumes the app is always served over HTTPS
setCookie("session", token, { secure: true, httpOnly: true });
emdashkits.com

A cookie config that quietly assumes "we're always on HTTPS" breaks the instant you test over plain HTTP, which local dev servers commonly are.

Read also:

Fix

// after -- derive secure from the actual request protocol
const isHttps = request.url.startsWith("https://");
setCookie("session", token, { secure: isHttps, httpOnly: true });
emdashkits.com

Lessons learned

  • Any Secure-flagged cookie needs to key off the real request scheme, not an assumption baked in once at cookie-creation time.
  • "Works in production, silently fails in local dev" is a strong signal to check cookie flags before anything else in an auth flow.
  • Check other cookies in the same codebase for the same hardcoded assumption — if one cookie has this bug, sibling cookies set the same way are worth auditing too.
Share
Previous Article

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

Comments

Write a comment

Related Articles

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

July 16, 2026

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

July 16, 2026

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

Uploaded Images Disappear After Every Deploy on Shared Hosting (and Other Reverse-Proxy Gotchas)

July 16, 2026

Uploaded Images Disappear After Every Deploy on Shared Hosting (and Other Reverse-Proxy Gotchas)

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

Google Analytics (GA4) Not Tracking Anything and No Console Errors: Check Your CSP First

TL;DR — GA4's gtag.js snippet was installed correctly, the page loaded with no visible JavaScript error, and GA4's real-time report still showed zero activity. The CMS's default Content-Security-Policy had no allowance for analytics domains and no config option to add one — so every request to Google's tracking endpoints was blocked at the browser level before it could fail loudly.

Table of Contents
  1. Diagnostic
  2. Root cause
  3. Lessons learned

Diagnostic

Check the browser's dedicated CSP violation reporting, not the regular console error list — CSP blocks are reported through their own channel, not thrown as normal script errors, so "no console errors" doesn't mean nothing was blocked.

Root cause

The CSP's script-src and connect-src directives had no entry for googletagmanager.com or google-analytics.com, and the CMS exposed no configuration surface to add one — the only way in was patching the CSP directives directly.

// patch-package: add analytics domains to the existing CSP directives
scriptSrc.push("https://www.googletagmanager.com");
connectSrc.push("https://www.google-analytics.com", "https://www.googletagmanager.com");
emdashkits.com
Read also:

Lessons learned

  • "No console errors" is not proof nothing was blocked — CSP violations live in their own reporting surface and are easy to miss if you're only scanning for red error text.
  • Before adding any third-party script tag to a site with a CSP already in place, check the CSP's directives first rather than assuming a silently-empty analytics dashboard means a snippet-installation mistake.
Share
Previous Article

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

Next Article

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

Comments

Write a comment

Related Articles

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

July 16, 2026

Login Works in Production but Fails on localhost: The secure Cookie Flag Gotcha

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

July 16, 2026

Native Module Build Fails on Shared Hosting (node-gyp, Old glibc/Python): The .npmrc Fix

Uploaded Images Disappear After Every Deploy on Shared Hosting (and Other Reverse-Proxy Gotchas)

July 16, 2026

Uploaded Images Disappear After Every Deploy on Shared Hosting (and Other Reverse-Proxy Gotchas)