SYSTEM Cited by 3 sources
EmDash¶
EmDash (emdash-cms/emdash, emdashcms.com) is Cloudflare's open-source TypeScript CMS, positioned as "the spiritual successor to WordPress." v0.1.0 preview launched 2026-04-01. Written entirely in TypeScript; powered by Astro for frontend rendering; runs serverless on Cloudflare Workers (workerd) or any Node.js server; MIT licensed. EmDash 1.0 (stable release, 2026-09-28) added a decentralized plugin registry, cross-platform plugin sandboxing, and an open-source AI site builder — see below.
v1.0 (2026-09-28): stable release¶
After ~5 months of work with contributors and production users, EmDash reached 1.0 — a "stable, free, and open source CMS built on Astro, ready to power a production website." The release hardened the parts every site depends on: data safety, database migrations, editorial workflows, localization, plugin security, performance, and the reliability of the admin / API / MCP / media experiences. Community scale at 1.0: 175+ contributors, 1,800+ commits, 25 languages, 800+ Discord members. (Source: sources/2026-09-28-cloudflare-emdash-10-the-stable-cms-with-a-secure-plugin-registry)
Customer Zero → GA features. Cloudflare migrated its own blog to EmDash in 2026-08 (the "Customer Zero" approach), which had to comfortably handle millions of pageviews/week, spikes up to 5,000 RPS of legitimate traffic, and sporadic DDoS. Features spawned by that migration are now GA for all customers: optional KV object caching, the Hyperdrive database adapter, and Workers Cache compatibility. (See sources/2026-08-24-cloudflare-the-cloudflare-blog-brought-to-you-by-emdash for the migration mechanics.)
Decentralized plugin registry (2026-09-28)¶
The EmDash plugin registry lets developers publish sandboxed plugins and site owners discover, inspect, and install them — without a central authority that owns the ecosystem. Its design principle: separate the plugin from the catalog. Traditional registries fuse three roles — the publisher's account, the authoritative package record, and the discovery catalog — making one company the gatekeeper for both identity and distribution. EmDash splits them: publishers retain their packages and release history; EmDash provides "a convenient place for people to find and install them"; other services can index the same publications and apply their own policies. This is the structural break of the plugin-marketplace-lock-in dynamic at the distribution layer (the capability sandbox breaks it at the execution layer).
Built on AT Protocol (atproto). Plugin authors publish with an Atmosphere account — the portable identity used across Bluesky and other atproto apps — and the package + release records are signed by the publisher and stored in the publisher's own account. Cloudflare hosts the default registry services so publishers/site-owners need not run infrastructure, but has open-sourced them all:
- the aggregator — powers the plugin registry.
- the labeler — uses Workers AI to moderate package descriptions.
- an Astro live content loader (
registry-loader) — embeds plugin listings in any Astro site.
Verification without trusting the catalog. "Atproto repositories use signed Merkle Search Trees, so an inclusion proof connects the exact release record to a signed commit from the publisher's account." EmDash verifies the record independently, then checks the plugin's checksum, package name, version, requested access, and any required build provenance, and confirms the downloaded bundle matches the signed record. "Decentralized publishing does not mean accepting unverified code." (Merkle Search Tree / inclusion-proof / build-provenance recorded as prose + tags, not minted as pages — single-source; see systems/at-protocol.)
Moderation without ownership. The catalog applies default content moderation to the names, descriptions, links, and images it displays — it can hide harmful material from this catalog but does not rewrite a release, take ownership of the plugin, or erase the underlying publication. Paid plugins are not yet supported but are on the roadmap (same decentralized model; Cloudflare is watching Atproto Spaces Alpha).
Cross-platform plugin sandboxing (Worker Loader / workerd)¶
At 1.0, EmDash made the sandbox model explicit and portable across runtimes. "Each plugin runs in an isolated runtime with access to its own private storage, but not to the site's content, media, users, secrets, environment, filesystem, or network. It gains additional abilities only when they are declared by the plugin and approved by the site administrator" — installing feels "more like installing a mobile app than a traditional CMS plugin."
Capabilities are independent. Granting media access does not expose users or unpublished content; allowing one outbound service does not open the rest of the network. "These boundaries are enforced by the runtime, not left to the plugin author's good intentions." Worked matrix from the post:
| A plugin could… | It might need to… | It still cannot… |
|---|---|---|
| Index published articles for search | Read content + contact the search service | Edit articles or contact other hosts |
| Optimize uploaded images | Read and manage media | Read user content |
| Send publishing notifications | Observe publishing + send email | Change the content being published |
| Provide configurable webhooks | Read selected events + contact public destinations | Reach private networks or other plugins' storage |
Two runtimes, one model:
- On Cloudflare — each plugin runs as a Dynamic Worker through the Worker Loader.
- On Node.js — EmDash starts workerd (the open-source Workers runtime) as a separate process and runs each plugin as an isolated service inside it.
"Plugins use the same manifests and capability-gated APIs on either platform." The isolation model is not Cloudflare-specific. See concepts/capability-based-sandbox.
From a single site to a website platform¶
EmDash powers an individual Astro site but is also designed for companies building website-creation / hosting products. Workers for Platforms lets those companies run each customer's site as a Worker on Cloudflare's global network — no per-site server provisioning or bespoke networking/deployment infra. EmDash supplies the content layer: platforms use the admin directly, build on the API + CLI, or put an agent in front of the built-in MCP server ("a bakery owner could update opening hours by asking for the change in plain language"). The sandboxed plugin model lets platforms offer extensions across many customer sites safely, and run their own marketplaces — full-registry access or a curated, pre-approved selection.
EmDash Build: open-source AI site builder (alpha)¶
EmDash Build is an open-sourced (alpha) AI site builder that hosting providers / platforms can self-run. Instead of throwaway prompt output, it "creates an EmDash site… the full stack: server-rendered Astro pages, a database, media storage, and an admin interface." The agent designs a content model from the brief, fills it in through EmDash's MCP server, and writes the pages that display it. Architecture:
- Each project gets its own Cloudflare Sandbox container, where the agent (built on the Agents SDK) "verifies its own work."
- Artifacts tracks every change as a git commit.
- On publish, content moves into a production EmDash site and deploys to the host's Workers for Platforms namespace.
Design thesis¶
WordPress's plugin architecture is structurally insecure — 96% of WordPress CVEs originate in plugins — because plugins are PHP scripts with direct access to WordPress's database and filesystem (no isolation). The WordPress.org marketplace exists to provide trust the platform can't, and because plugins run in the same execution context as WordPress itself, the GPL-inheritance argument locks plugin authors to the marketplace. EmDash inverts this: plugins are sandboxed; the marketplace becomes optional. See plugin-marketplace-lock-in.
Plugin architecture — capability-manifest per Dynamic Worker¶
EmDash plugins run as Dynamic Workers with a capability manifest. Each plugin is a fresh capability-based sandbox isolate. The manifest declares exactly which hooks and capabilities the plugin needs:
definePlugin({
id: "notify-on-publish",
version: "1.0.0",
capabilities: ["read:content", "email:send"],
hooks: {
"content:afterSave": async (event, ctx) => {
if (event.content.status !== "published") return;
await ctx.email!.send({ /* ... */ });
},
},
});
Runtime-enforced properties:
- No ambient authority. No filesystem access, no database access, no arbitrary network — unless granted via a capability.
- Per-hostname network egress. Plugins specify exact hostnames in their definition; network calls to anything else fail at the runtime boundary.
- Declared hooks only. A plugin can only observe content lifecycle events it declared.
- Capabilities are install-time inspectable. An administrator can grant or refuse based on what the plugin requests, without reading plugin code.
Canonical instance of capability-manifest-plugin-isolation.
License-independent plugins¶
Two structural consequences of the sandbox model:
- Plugins can have any license. They run independently of EmDash core and share no code. Plugin authors pick the license — MIT, proprietary, AGPL, anything.
- Plugin code can be trusted without being seen. "A plugin can be provided to an EmDash site, and trusted, without the EmDash site ever seeing the code." The manifest + capability boundary is what's inspected, not the implementation.
Canonical instance of license-independent-sandboxed-plugins.
Theming — Astro¶
EmDash themes are Astro projects. Familiar to frontend developers, trained into LLMs, optimised for content sites. A theme includes:
- Pages (Astro routes)
- Layouts (shared HTML structure)
- Components (reusable UI)
- Styles (CSS or Tailwind)
- Seed file (JSON describing content types and fields)
Themes cannot perform database operations — explicitly
contrasted with WordPress themes' functions.php execution
environment, which has the same power (and same risks) as
plugins. EmDash themes inherit the sandbox model.
Scale-to-zero serverless hosting¶
EmDash is built to run on workerd (the open-source V8-isolate runtime under Workers). Workers instantly spins up an isolate per request, scales back to zero when idle, bills only for CPU time. See concepts/scale-to-zero. Platform operators can host millions of EmDash instances via Cloudflare for Platforms.
Portability: EmDash also runs on any Node.js server. The scale-to-zero economics are Cloudflare-specific; the code is not locked in.
Built-in x402 / agentic commerce¶
Every EmDash site has x402 support built in. Configure which content requires payment, set the price, provide a wallet address — HTTP 402 Payment Required-based per-request pricing works out of the box. Canonical agentic paywall primitive in a CMS.
AI-native management surfaces¶
Three programmatic-management surfaces ship with every EmDash instance:
- Agent Skills — skill documents describe plugin capabilities, triggering hooks, a plugin-authoring skill, and a WordPress-theme-to-EmDash porting skill. Agents pointed at an EmDash codebase find the skills and work from them.
- EmDash CLI — programmatic equivalents of Admin UI actions (media upload, content search, schema create/manage).
- Built-in MCP Server — every EmDash instance exposes its own MCP server with the Admin UI's capability set.
Collapses the "rote migration of content" class of CMS work (find-and-replace, custom-field migration, bulk rename/reorder) from "one-off scripts or single-use plugins" to "agent tells the MCP server what to do."
Authentication — passkeys by default¶
Passkey / WebAuthn is the default — "no passwords to leak and no brute-force vectors to defend against." RBAC roles out of the box: administrator, editor, author, contributor.
Pluggable. Alternative auth backends (SSO via IdP) can auto-provision access based on IdP metadata.
WordPress migration path¶
Two options:
- WXR export. Standard WordPress export file, imported via EmDash admin. Works for content + attached media.
- EmDash Exporter WordPress plugin. Installs on a live WordPress site, exposes a secure endpoint protected by a WordPress Application Password, migrates content continuously.
Custom post types (previously requiring heavy plugins like Advanced Custom Fields) map onto EmDash's native schema/collections model — defined in the admin panel, stored in separate collections rather than squeezed into the posts table.
Openness¶
- MIT license. Permissive; can be forked, extended, relicensed in combinations.
- No WordPress code used. Clean-room TypeScript reimplementation of WordPress's functionality set. The "no WordPress code" claim is what unlocks the permissive license relative to WordPress's GPL.
- GitHub-hosted, community PRs welcome, developer beta as of 2026-04.
Architectural relationship to Project Think / Dynamic Workers¶
EmDash applies the same
capability-based
sandbox primitive that
Project Think uses for
LLM-generated code, at a different layer: third-party
plugins in a CMS. The manifest-then-grant shape is
identical — Project Think's
{network: ["api.github.com"], workspace: "read-write"}
agent-extension manifest is the same move as EmDash's
capabilities: ["read:content", "email:send"] plugin
manifest. EmDash is the "user-uploads-a-plugin" variant
of the "agent-writes-its-own-tool" pattern.
Seen in¶
- sources/2026-04-01-cloudflare-emdash-wordpress-spiritual-successor — canonical wiki instance. Launch post; architecture overview; the capability-manifest plugin model; x402 built-in; MCP + Agent Skills + passkey defaults; MIT-license + clean-reimplementation-over-WordPress story.
- sources/2026-08-24-cloudflare-the-cloudflare-blog-brought-to-you-by-emdash — EmDash in production as Cloudflare's own blog CMS, with Cloudflare as Customer Zero. The 2026-08-12 migration validated EmDash on Workers against real blog traffic (~75 RPS normal, >5,000 RPS spikes) via k6 load tests, layered multiple caches (99.5% static / ~70% overall cache hit), and cut over with zero downtime via a proxy Worker. Also shipped a Cloudflare Blog MCP server and used EmDash's own authoring MCP. Surfaced real early-version gaps (scheduled posts broken until v0.19.0). First wiki instance of EmDash running in production rather than as a launch announcement.
- sources/2026-09-28-cloudflare-emdash-10-the-stable-cms-with-a-secure-plugin-registry — EmDash 1.0 (stable release). The decentralized plugin registry on atproto (publisher-signed records + Merkle-Search-Tree inclusion proofs + Workers-AI labeler moderation, separating plugin from catalog); the cross-platform capability sandbox (Worker Loader on Cloudflare / workerd subprocess on Node.js) with independent, install-time-approved capabilities; EmDash as a Workers-for-Platforms website platform; and the open-sourced EmDash Build AI site builder (per-project Cloudflare Sandbox
- Artifacts git-commit tracking). Customer-Zero blog migration spawned GA KV object cache + Hyperdrive adapter + Workers Cache compat.
Related¶
- systems/wordpress — incumbent; positioned as successor to.
- systems/astro — theming framework.
- systems/dynamic-workers — per-plugin isolate substrate (Worker Loader on Cloudflare).
- systems/workerd — subprocess runtime giving the same per-plugin isolation on Node.js.
- systems/cloudflare-workers — serverless runtime.
- systems/at-protocol — decentralized substrate for the plugin registry (signed records + Merkle Search Trees).
- systems/workers-for-platforms — multi-tenant hosting for EmDash-as-a-platform.
- systems/workers-ai — powers the registry's labeler moderation.
- systems/cloudflare-sandbox-sdk — per-project container for EmDash Build's self-verifying agent.
- systems/cloudflare-artifacts — git-commit change tracking in EmDash Build.
- systems/hyperdrive / systems/cloudflare-kv — DB adapter + object cache spawned by the Customer-Zero migration.
- systems/model-context-protocol — agent-management surface.
- systems/agent-skills — plugin-authoring / porting guidance.
- systems/x402-protocol — built-in monetisation.
- concepts/capability-based-sandbox — plugin-isolation primitive.
- capability-manifest — the declarative install-time contract.
- plugin-marketplace-lock-in — the dynamic EmDash argues against.
- passkey-authentication — default auth.
- concepts/scale-to-zero — hosting-cost model.
- http-402-payment-required — x402 substrate.
- capability-manifest-plugin-isolation — composed primitive.
- license-independent-sandboxed-plugins — distribution-model consequence.
- per-request-isolate-per-plugin — runtime posture.
- companies/cloudflare — operator.