{"id":98008,"date":"2026-10-04T19:50:00","date_gmt":"2026-10-04T23:50:00","guid":{"rendered":"https:\/\/overcentral.com\/en\/?p=98008"},"modified":"2026-09-29T07:52:42","modified_gmt":"2026-09-29T11:52:42","slug":"emdash-self-hosting-plugin-sandbox-98008","status":"publish","type":"post","link":"https:\/\/overcentral.com\/en\/emdash-self-hosting-plugin-sandbox-98008\/","title":{"rendered":"The Dark Side of EmDash: Why Self-Hosting Means Losing Its Killer Feature"},"content":{"rendered":"<p>Everyone says the same thing about <a href=\"https:\/\/emdash.dev\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">EmDash<\/a>: it&#8217;s open source, MIT-licensed, and you can run it anywhere \u2014 your own server, AWS, a Raspberry Pi. &#8220;Not locked in.&#8221; That&#8217;s the pitch. You hear it from Cloudflare&#8217;s own blog, from early adopters, from every Hacker News comment that wants to sound reasonable.<\/p>\n<p>They&#8217;re technically right. The code is on GitHub. You can <code>npm create emdash-latest<\/code>codecodecodecodecode and deploy to any Node.js host. But here&#8217;s what nobody tells you in those glowing first impressions: the one feature that justifies EmDash&#8217;s existence \u2014 the plugin sandbox \u2014 vanishes the moment you leave Cloudflare&#8217;s runtime. Self-hosting EmDash is like buying a bulletproof car and removing the armor before you drive it.<\/p>\n<p>Let&#8217;s be specific about what you lose.<\/p>\n<h2>The Plugin Sandbox Is Not Optional \u2014 It&#8217;s the Product<\/h2>\n<p><a href=\"https:\/\/www.cloudflare.com\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">Cloudflare<\/a> built EmDash to solve a single, well-documented problem. 96% of all WordPress security vulnerabilities come from plugins. In 2025 alone, researchers disclosed 11,334 new WordPress vulnerabilities \u2014 a 42% increase from the year before. Nearly half were exploitable without any authentication. The root cause isn&#8217;t bad plugin code; it&#8217;s the architecture. Every WordPress plugin runs in the same process as the core, with full access to the database, file system, and user sessions. Install a contact form plugin with a bug, and an attacker can read your entire database.<\/p>\n<p>EmDash&#8217;s answer: every plugin runs in its own V8 isolate, a lightweight sandboxed environment that cannot touch anything unless a capability manifest explicitly grants it. A plugin that declares <code>read content<\/code>codecodecodecodecode and <code>send email<\/code>codecodecodecodecode can literally do nothing else \u2014 no database queries, no file system access, no unrestricted network calls. This isn&#8217;t policy; it&#8217;s architectural enforcement via dynamic workers.<\/p>\n<p>That&#8217;s the killer feature. That&#8217;s the reason to switch from WordPress.<\/p>\n<p>Now read the fine print.<\/p>\n<h3>Self-Hosted EmDash: No Sandbox, No Isolation<\/h3>\n<p>The EmDash documentation is honest about this. <a href=\"https:\/\/overcentral.com\/en\/eu-cra-reporting-requirements-80362\/\" title=\"EU CRA Demands What Shipped and When You Knew\" data-iacss-internal=\"1\">When you<\/a> self-host on a regular Node.js server, plugins run <strong>in-process<\/strong> \u2014 the same model WordPress uses. No V8 isolate, no capability manifest enforcement, no sandbox. The plugin has full access to your database, your file system, your user data. Exactly the problem EmDash was supposed to fix.<\/p>\n<p>Cloudflare&#8217;s lead engineer Matt Cain confirmed this in a podcast interview: &#8220;For the kind of plugins that very often end up having the biggest blast area in taking down your entire site, this does solve the vast majority of those kind of problems.&#8221; But he was talking about the sandboxed environment that only runs on Cloudflare&#8217;s runtime.<\/p>\n<p>Even on Cloudflare&#8217;s free tier, plugins run in &#8220;in-process mode&#8221; \u2014 no real isolation. The sandbox only activates when you&#8217;re on the Workers Paid Plan, which starts at $5\/month and requires dynamic workers. Without that, you&#8217;re running a brand-new CMS with zero plugins and no security advantage over WordPress.<\/p>\n<p>So the common advice \u2014 &#8220;self-host to avoid vendor lock-in&#8221; \u2014 ignores a critical trade-off: you&#8217;re trading Cloudflare lock-in for a fundamentally less secure product.<\/p>\n<h2>The Architecture That Makes the Sandbox Possible Is Proprietary<\/h2>\n<p>Dynamic workers are not a standard Node.js feature. They&#8217;re a Cloudflare-specific product that runs on V8 isolates across Cloudflare&#8217;s 300+ data centers. The isolation model uses Linux namespaces, seccomp filters, and hardware memory protection keys \u2014 none of which exist in a typical Node.js deployment.<\/p>\n<p>When you self-host, you get none of that. The code that makes the sandbox work is open source, but the runtime that enforces it is not. Cloudflare&#8217;s own blog post admits: &#8220;Plugins run in their own isolated container called a dynamic worker.&#8221; That container is a Cloudflare Workers feature, not something you can replicate on a $5 VPS.<\/p>\n<p>One widely upvoted Hacker News comment put it bluntly: &#8220;Open source, but architecturally locked in.&#8221; WordPress runs on any server with PHP and MySQL; you can switch hosting providers in an afternoon. EmDash&#8217;s data is portable \u2014 D1 is SQLite-based, R2 is S3-compatible \u2014 but the security model isn&#8217;t. The feature that justifies EmDash&#8217;s existence requires Cloudflare&#8217;s paid infrastructure.<\/p>\n<h3>What You Actually Get on a Self-Hosted Instance<\/h3>\n<p>Let&#8217;s walk through what a self-hosted EmDash installation looks like today.<\/p>\n<ul>\n<li><strong>Zero sandboxed plugins.<\/strong> The only way to run plugins with isolation is via dynamic workers on Cloudflare&#8217;s paid plan. Without that, plugins are just Node.js scripts with full system access.<\/li>\n<li><strong>No performance advantage.<\/strong> The V8 isolate cold-start time is sub-5 milliseconds on Cloudflare&#8217;s edge. On a Node.js server, you&#8217;re dealing with process-level overhead and no auto-scaling to zero.<\/li>\n<li><strong>No <a href=\"https:\/\/overcentral.com\/en\/meta-muse-ai-agent-80441\/\" title=\"Meta Launches Muse AI Agent, Needs User Trust\" data-iacss-internal=\"1\">AI agent<\/a> integration.<\/strong> The built-in MCP server and agent skills still work, but the ability to let AI generate and run code safely depends on dynamic workers. Without them, you&#8217;re back to trusting AI-generated scripts with full access to your database.<\/li>\n<li><strong>No unlimited storage.<\/strong> EmDash on Cloudflare uses R2 with zero egress fees. Self-hosted, you&#8217;re paying for blob storage and bandwidth like any other CMS.<\/li>\n<\/ul>\n<p>The value proposition collapses. You get a UI that looks like WordPress, a block editor, and a few built-in features like SEO and custom content types \u2014 but the core architectural innovation is gone.<\/p>\n<h2>Why the &#8220;Self-Host Anywhere&#8221; Advice Is Dangerous<\/h2>\n<p>The most common rebuttal from EmDash advocates is: &#8220;But you can self-host on any Node.js server!&#8221; That&#8217;s true in the narrowest sense \u2014 the code runs. But it ignores the context of why you&#8217;d choose EmDash in the first place.<\/p>\n<p>If you&#8217;re running a simple blog and don&#8217;t need plugins, WordPress on a $5 VPS works fine. If you need a modern TypeScript stack, there are dozens of headless CMS options. The only reason to pick EmDash over those alternatives is the sandboxed plugin architecture. Remove that, and you&#8217;re left with a beta-quality CMS that has fewer features, fewer plugins, and a smaller community than WordPress.<\/p>\n<p>Consider the migration path. EmDash&#8217;s WordPress import tool brings over posts, pages, and media \u2014 but not plugins, themes, or custom functionality. If you self-host EmDash and need any non-trivial feature (e-commerce, advanced forms, membership systems), you have to build it from scratch or install an in-process plugin that defeats the entire security model. At that point, you might as well have stayed on WordPress.<\/p>\n<h3>The Billing Nightmare Is Real \u2014 Even on Cloudflare<\/h3>\n<p>Self-hosting advocates also point to unpredictable Cloudflare billing as a reason to avoid the paid plan. They&#8217;re not wrong. The serverless model means every page view, admin panel click, and API call triggers a worker invocation. A small DDoS attack can rack up $13,000 in a single night \u2014 and there is no built-in spending cap. That&#8217;s a legitimate concern.<\/p>\n<p>But the solution isn&#8217;t to self-host and lose the sandbox. The solution is to understand that EmDash, in its current form, is not a WordPress replacement for most users. It&#8217;s a developer preview of a new security model that only works on Cloudflare&#8217;s infrastructure. Self-hosting it is like buying a sports car and removing the engine \u2014 you still have wheels and a chassis, but the whole point is gone.<\/p>\n<h2>The Honest Assessment<\/h2>\n<p>The &#8220;self-host anywhere&#8221; advice is incomplete. It frames the <a href=\"https:\/\/overcentral.com\/en\/ichra-choice-arrangements-label-97925\/\" title=\"ICHRA Gets CHOICE Arrangements Label from CMS, SBA\" data-iacss-internal=\"1\">choice<\/a> as freedom versus lock-in, but the real choice is between a secure architecture and an insecure one. EmDash without the sandbox is not &#8220;EmDash on your own terms&#8221; \u2014 it&#8217;s a crippled version of a product that hasn&#8217;t even reached version 1.0.<\/p>\n<p>Cloudflare has been transparent about this. The README says &#8220;EmDash works best on Cloudflare&#8221; and notes that sandboxed plugins require dynamic workers. But the marketing language \u2014 &#8220;spiritual successor to WordPress,&#8221; &#8220;open source, MIT licensed&#8221; \u2014 creates an expectation that the full feature set is portable. It isn&#8217;t.<\/p>\n<p>If you&#8217;re a developer experimenting with new CMS architectures, by all means, self-host EmDash and kick the tires. But if you&#8217;re a business owner, an agency building client sites, or anyone who needs a production-ready CMS, self-hosting EmDash today means accepting a security model that is architecturally identical to WordPress \u2014 without the ecosystem, the battle-testing, or the 20 years of community contributions.<\/p>\n<p>The real question isn&#8217;t &#8220;Can I self-host EmDash?&#8221; It&#8217;s &#8220;Why would I, when the only thing that makes it special requires a Cloudflare account?&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Everyone says the same thing about EmDash: it&#8217;s open source, MIT-licensed, and you can run it anywhere \u2014 your own server, AWS, a Raspberry Pi. &#8220;Not locked in.&#8221; That&#8217;s the pitch. You hear it from Cloudflare&#8217;s own blog, from early adopters, from every Hacker News comment that wants to sound reasonable. They&#8217;re technically right. The [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":99155,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98008.png","fifu_image_alt":"The Dark Side of EmDash: Why Self-Hosting Means Losing Its Killer Feature","footnotes":""},"categories":[31],"tags":[],"class_list":["post-98008","post","type-post","status-publish","format-standard","has-post-thumbnail","category-technology"],"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98008.png","fifu_image_alt":"The Dark Side of EmDash: Why Self-Hosting Means Losing Its Killer Feature","_links":{"self":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/comments?post=98008"}],"version-history":[{"count":1,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98008\/revisions"}],"predecessor-version":[{"id":99156,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98008\/revisions\/99156"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media\/99155"}],"wp:attachment":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media?parent=98008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/categories?post=98008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/tags?post=98008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}