EmDash: A WordPress Successor Built on Astro and Cloudflare Workers
EmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress.
At a glance
- What is it?
- EmDash is a full-stack TypeScript CMS that reimagines WordPress concepts on Astro and Cloudflare, with sandboxed plugins and structured content. This review covers its architecture, setup, limitations, and who should adopt it.
- Who is it for?
- Adopt EmDash if you want a modern, type-safe CMS that runs on Cloudflare's free tier or a Node.js server with SQLite, and you value plugin security and structured content. Do not adopt it if you need a mature ecosystem, on-premises hosting without Cloudflare, or you cannot pay for Cloudflare's paid plan to enable plugins.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem EmDash Solves
EmDash targets the same problem WordPress solved in 2003: giving non-developers a way to manage content while letting developers extend the system. But it does so with modern constraints. The README cites that 96% of WordPress security vulnerabilities come from plugins, and that WordPress requires managing PHP alongside JavaScript and layering caches. EmDash replaces PHP with TypeScript, runs on serverless infrastructure, and isolates plugins in sandboxed Worker isolates. It is for teams that want a CMS with an admin panel, REST API, and plugin ecosystem, but without the legacy baggage of PHP or the security risk of plugins with full database and filesystem access.
Architecture: Astro Integration, Database-Defined Content
EmDash is an Astro integration, not a standalone server. You add it to your astro.config.mjs file, and it provides the admin panel, REST API, authentication, media library, and plugin system. Content types are defined in the database, not in code. The admin UI lets non-developers create and modify collections, and each collection gets a real SQL table with typed columns. Developers generate TypeScript types from the live schema using `npx emdash types`. Querying content uses Astro's Live Collections, which means no rebuilds and no separate API. The data flow is direct: your Astro site reads from the database through the integration, and the admin panel writes to the same database. This is a fundamental shift from WordPress, where content is stored as serialized HTML with embedded metadata. EmDash uses Portable Text, a structured JSON format, so content can render to web, mobile, email, or API responses without parsing HTML.
Getting Started: Commands and Configuration
The README gives a single command to start: `npm create emdash@latest`. This scaffolds a new project. You can also deploy directly to Cloudflare via a deploy button that links to a template repository. The configuration is minimal. In astro.config.mjs, you import emdash from "emdash/astro" and a database adapter from "emdash/db", then pass an options object. The example shows `emdash({ database: d1() })` for Cloudflare D1. The README includes a critical note: EmDash depends on Dynamic Workers to run sandboxed plugins, and Dynamic Workers are currently only available on paid Cloudflare accounts (starting at $5/mo). If you do not upgrade, you can comment out the `worker_loaders` block in your wrangler.jsonc file to disable plugins. This is a real constraint that affects setup on the free tier.
Plugin Sandboxing: The Core Innovation and Its Cost
The plugin system is the most distinctive feature. Plugins run in isolated Worker sandboxes via Dynamic Worker Loaders, and each plugin declares a capability manifest. The README shows a plugin that requests `read:content` and `email:send`, and the example hook `content:afterSave` sends an email when content is published. This is a genuine security improvement over WordPress, where a plugin can access everything. However, the sandboxing comes with a cost: it requires Cloudflare's paid Dynamic Workers feature. Without it, you must run plugins in-process, which the README calls "safe mode" in the Portable Platforms table. That mode likely negates the sandboxing benefit. Also, the plugin API is new and likely has a smaller ecosystem than WordPress. The README mentions agent skills for building plugins, but there is no evidence of a mature plugin marketplace. You are betting on a young ecosystem.
Structured Content and Portability
EmDash uses Portable Text for rich text, which is a structured JSON format. This decouples content from its presentation, unlike WordPress's HTML-with-comments approach. The README claims this allows content to render as a web page, mobile app, email, or API response without parsing HTML. That is a real advantage for headless or multi-channel use cases. The storage layer is portable too: it uses Kysely for SQL and S3 API for storage. The supported databases include D1, SQLite, Turso/libSQL, and PostgreSQL. Storage options include R2, AWS S3, any S3-compatible service, and local filesystem. Sessions work with KV, Redis, or file-based storage. This means you are not locked to Cloudflare, even though that is the primary target. The README says it "runs best on Cloudflare, but it's not locked to it." If you want to run on a Node.js server with SQLite, you can, but you lose the sandboxed plugin execution.
Limitations and When It Is the Wrong Tool
The most obvious limitation is the dependency on Cloudflare's paid Dynamic Workers for plugin sandboxing. If you are on the free tier, you must disable plugins, which removes a major feature. Another limitation is the beta status. The README says EmDash is in "beta preview," which implies API changes and potential instability. There is no mention of a stable release or long-term support. The admin panel and plugin ecosystem are new, so expect fewer third-party themes and plugins than WordPress. Also, the content model is database-defined, not code-defined. This is powerful for non-developers, but it means your schema is not version-controlled unless you export it. If you need a CMS that runs on traditional shared hosting or on-premises servers without Cloudflare, EmDash is not the right choice. It is designed for serverless or Node.js with SQLite, but the plugin sandboxing only works on Cloudflare.
Alternatives: Comparing Approaches
The obvious alternative is WordPress itself, but that is the incumbent EmDash is trying to replace. A more relevant comparison is Directus or Strapi, which are also headless CMSs with structured content. Directus uses a database-first approach with a REST and GraphQL API, and it runs on Node.js with any SQL database. Strapi is code-first, where content types are defined in JavaScript and then stored in a database. EmDash differs in that it is an Astro integration, so it lives inside your Astro project rather than being a separate service. Also, EmDash's plugin sandboxing is unique; Directus and Strapi have plugin systems but they run in the same process as the server, which is similar to WordPress's security model. If you need a plugin system with strict isolation, EmDash is the only one of these with that feature, but it requires Cloudflare. If you want a mature ecosystem and don't need sandboxing, Directus or Strapi might be safer bets.
Maintenance and Upgrade Costs
The repository shows active development with recent releases at version 0.35.0, so there is a regular release cadence. However, being in beta means breaking changes are possible between minor versions. The README mentions a documentation site and a development setup using pnpm, but it does not provide upgrade guides or migration paths. You will need to follow the changelog and test after each update. The license is MIT, which is permissive and allows commercial use without restrictions. There is no mention of a paid tier for EmDash itself, but the Cloudflare dependency means you may incur costs for Dynamic Workers. The WordPress import wizard helps migrate existing content, but porting plugins and themes is not automatic; the README says agent skills help, but that is not a guarantee. Before adopting, verify that the import wizard handles your specific WordPress setup and that your plugins have equivalents in EmDash's ecosystem.
Editorial conclusion
Adopt EmDash if you want a modern, type-safe CMS that runs on Cloudflare's free tier or a Node.js server with SQLite, and you value plugin security and structured content. Do not adopt it if you need a mature ecosystem, on-premises hosting without Cloudflare, or you cannot pay for Cloudflare's paid plan to enable plugins. Before committing, verify that Dynamic Workers are available in your Cloudflare account, test the WordPress import wizard with a sample WXR file, and review the plugin capability manifest to ensure it meets your security requirements.
Community notes