---
title: "EmDash CMS Review: 6 Monate später, nach dem 1.0-Release"
description: "Ein ehrliches EmDash-CMS-Review nach sechs Monaten und dem 1.0-Release: Was sich geändert hat, Cloudflare vs. Self-Hosted-VPS-Deploy, Ops-Fallen und für wen es wirklich ist."
date: 2026-09-29
categories: ["web-development"]
tags: ["emdash","astro","cloudflare"]
---

*Hinweis: Dieser Artikel enthält Referral-/Affiliate-Links. Wenn du darüber kaufst, erhalte ich möglicherweise eine Provision – ohne zusätzliche Kosten für dich.*

Dieses EmDash-CMS-Review wird sechs Monate geschrieben, nachdem Cloudflares WordPress-Nachfolger am 1. April 2026 geshipt wurde, und Tage nach dem 1.0-Release. Jede unabhängige Einschätzung, die du gerade findest, ist ein April-Ersteindruck einer 0.x-Beta. Diese Beta ist weg. `emdash@1.0.1` ist live auf npm, die Plugin-Registry steht, und der Cloudflare-Blog selbst läuft seit dem 12. August auf EmDash.

Wenn du „was ist EmDash CMS" googelst und ob es produktionsreif ist, die kurze Version: Es ist jetzt ein echtes CMS, mit Produktions-Beweis in einem Ausmaß, das fast nichts anderes in diesem Markt vorweisen kann, und einem wirklich neuartigen Plugin-Sicherheitsmodell. Es ist außerdem immer noch Astro-only, du besitzt die Datenbank, und die Admin-UX ist jung. Ob dieser Trade für dich funktioniert, hängt von einer Weggabelung ab, und dieses Review läuft sie Ende zu Ende: Cloudflare all-in (Workers + D1 + R2) gegen Self-Hosted-Node.js auf einem günstigen VPS mit SQLite und S3-Backups.

Was folgt, ist die Ops-Tiefe, die kein April-Artikel hatte: echte Deploy-Configs, Kostenrechnung in Größenordnungen, die Failure Modes aus EmDashs eigenen Troubleshooting-Docs und ein Fazit pro Persona. Alle Metriken sind datiert „Stand September 2026", damit du sie zum Publish-Zeitpunkt gegenprüfen kannst.

Video: [WordPress Is Broken. Can emdash Replace It?](https://www.youtube.com/embed/1X6KwMjbv-Y)

## Was ist EmDash CMS? Cloudflares WordPress-Nachfolger, erklärt

EmDash ist ein Full-Stack-TypeScript-CMS, gebaut als Astro-Integration. MIT-lizenziert, kein WordPress-Code, angekündigt am 1. April 2026 als „spiritual successor to WordPress" und Ende September 2026 als `emdash@1.0.1` geshipt. Ein Deployment trägt die Astro-Site, das Admin-Panel, eine REST-API, Passkey-first-Auth, eine Media Library und ein Plugin-System. Das ist der ganze Punkt: CMS plus Website in einer Anwendung.

Die Architektur zählt mehr als die Feature-Liste:

- **Astro-Integration**, konfiguriert in `astro.config.mjs` als `emdash()`. Die Peer-Dependency ist `astro >= 6`.
- **Live Content Collections**: Server-gerenderte Seiten lesen veröffentlichte Inhalte zur Request-Zeit. Die Änderung eines Redakteurs taucht beim nächsten Request ohne Rebuild auf. Prerendered Pages bleiben statisch, bis du neu buildst.
- **Inhalte leben in der Datenbank**, nicht in deinem Repo. Redakteure arbeiten im Admin unter `/_emdash/admin`; Entwickler fahren `npx emdash types`, um TypeScript-Deklarationen zu generieren (`emdash-env.d.ts` aktualisiert sich in Dev selbst).
- **Portable-Text**-Inhaltsformat (strukturiertes JSON, kein serialisiertes HTML). TipTap ist der Rich-Text-Editor. Es gibt einen `gutenberg-to-portable-text`-Konverter für WordPress-Importe.
- **Kysely-SQL-Adapter**: D1, SQLite, libSQL oder Postgres. Medien gehen nach R2, jede S3-API oder lokale Disk.
- **MCP-Server in jedem Install eingebaut** unter `/_emdash/api/mcp`, mit rund 60 Tools (Content-CRUD, Publish, Schedule, Media, Schema, Taxonomies) plus Plugin-Tools. Nur Bearer-Token-Auth: OAuth 2.1 mit PKCE, Personal Access Tokens oder `emdash login` Device Grant. Seit 0.37.0 erfordern Updates den `_rev`-Concurrency-Token, sodass ein Agent nicht blind über die Änderungen eines Redakteurs schreiben kann.
- **x402-Payments eingebaut**: Inhalt als paid markieren, Preis und Wallet-Adresse setzen, und Agents bekommen HTTP 402, zahlen und lesen. Interessantes Primitive, kein Revenue-Plan (echtes x402-Volumen lag im April immer noch bei rund 28k $/Tag ökosystemweit).
- **Fünf Templates** zur `create-emdash`-Zeit, jedes mit einer Cloudflare- und einer Node/SQLite-Variante: blog, marketing, portfolio, starter und blank.

Node.js `>= 22.16` ist Pflicht, wenn du selbst hostest. Und eine Sache, die die Docs unverblümt sagen: EmDash ist kein visueller Page Builder. Astro-Komponenten besitzen das HTML. Wenn du Drag-and-Drop-Layout willst, ist das nicht dein Tool.

![EmDash-CMS-Architektur: Astro-Site mit Admin-Panel, REST-API und MCP-Server, die eine Datenbank und S3-kompatiblen Medien-Storage abfragen](@assets/images/26/09/emdash-architecture.svg)

**Die react()-Falle**

Die Admin-UI ist eine React-App, die `react()`-Astro-Integration ist also selbst auf einer reinen Astro-Site Pflicht. Vergisst du sie, bricht der Admin. Es ist ein leichtes Versehen in einer minimalen Config und das Erste, was du prüfst, wenn `/_emdash/admin` sich komisch verhält.

Diese React-Abhängigkeit kauft dir den Admin unten: den EmDash-v1.0-Post-Editor, über die offizielle Site.

![EmDash-v1.0-Admin-Interface: der Post-Editor mit Sidebar-Navigation, TipTap-Content-Bereich und einem Publish-Panel, das Live-Version gegen Draft-Änderungen trackt](@assets/images/26/09/emdash-admin.webp)

Wenn du das mit dem SaaS-Feld vergleichst, ist unser Beitrag zu den [besten Headless-CMS-Optionen für Astro](/best-headless-cms-for-astro/) der richtige Ort, um zu sehen, wo ein DB-gestütztes In-App-CMS gegenüber git-basierten und gehosteten Alternativen steht. Für Build-Speed-Kontext zum darunterliegenden Framework sieh [was Astro 7 für die Build-Geschwindigkeit geändert hat](/astro-7-faster-builds/) (EmDash 1.0.1 trackt Astro 7 schon in seinen devDependencies).

## Sechs-Monate-Check: 12,9k Sterne, 126k Downloads und eine große Migration

April-Reviews bewerteten eine 0.1-Preview. Sechs Monate Shipping später, hier der Projektgesundheits-Snapshot, Stand Ende September 2026:

| Metrik | Wert (Stand Sep 2026) | Quelle |
|---|---|---|
| GitHub-Sterne | ~12,9k (API-Snapshot: 12.971) | GitHub API |
| Forks | ~1,2k | GitHub API |
| Contributors | 175+ | Cloudflare-1.0-Post |
| Commits | 1.800+ | Cloudflare-1.0-Post |
| Offene Issues | 304 | GitHub API |
| npm-Downloads (`emdash`) | 126.332/Monat (29. Aug bis 27. Sep) | api.npmjs.org |
| npm-Downloads (`create-emdash`) | 3.228/Monat | api.npmjs.org |
| Releases | ~37 in 6 Monaten (0.1.0 bis 1.0.1) | GitHub Releases |
| Discord | 800+ Mitglieder | Cloudflare-1.0-Post |
| UI-Sprachen | 25 | Cloudflare-1.0-Post |
| Paketgröße | 23,1 MB unpacked, 2.489 Dateien | npm Registry |

Die Releases waren changesets-getrieben und signiert, mit npm Provenance via GitHub-Actions-OIDC-Trusted-Publishing und SLSA-Attestierungen auf 1.0.1. Das ist ernste Supply-Chain-Hygiene für ein CMS-Projekt von einem halben Jahr. Die Kadenz ist auch echt: 0.19.0 landete im August (das Release, das Scheduled Publishing endlich zum Laufen brachte), 0.37.0 am 9. September brachte Registry-Verifizierung und die `_rev`-Concurrency-Anforderung, und 1.0.1 kam Ende September. Maintainer sind Matt Kane (das `author`-Feld auf npm) und Noah Pham, der vom Intern zum zweiten Maintainer mit 80-plus Changesets wurde, plus Cloudflare-Staff in der Contributor-Liste. Sechs Monate drin ist das kein Ein-Personen-Repo.

Dann gibt es Kunde null. Der Cloudflare-Blog migrierte am 12. August 2026 zu EmDash, und die Zahlen sind der stärkste Produktions-Beweis in diesem Markt das ganze Jahr:

- ~75 RPS Baseline, Spitzen über 5.000 RPS, bis zu 850 RPS im Steady State serviert.
- k6-Load-Testing mit Ramp-, Breakpoint- und 7.000-RPS-Burst-Profilen. Schwellen: unter 0,01 % 5xx, P95 unter 500ms, P99 unter 1s.
- ~70 % aller Requests aus dem Cache serviert (99,5 % der statischen Dateien), mit flacher p95-Latenz, wo die Legacy-Plattform spiky war.
- Agents-Week-Stress: 28 Posts in 9 Tagen, ~3M Pageviews, 450 RPS sustained. Eine 28.000-RPS-DDoS wurde am 10. August am Cloudflare-Edge absorbiert, nicht von EmDash.
- Der Rollout war ein Proxy-Worker mit Version-Cookie, 1 % auf 5 % auf 15 % auf 100 % an einem Tag, mit Auto-Fallback auf den Legacy-Blog bei 500ern.

Zwei ehrliche Einschränkungen. Erstens: Ihr Stack ist kein normaler Deploy — Workers Cache, ein EmDash-Object-Cache auf Workers KV und Hyperdrive zu PlanetScale. Sie nutzten Postgres/MySQL via Hyperdrive, nicht D1. Dein Blog wird das nicht brauchen. Zweitens: Scheduled Publishing **funktionierte bis v0.19.0 überhaupt nicht**, eine Lücke, die Cloudflare mitten in der Migration entdeckte. Das ist die Art Bug, die nur auftaucht, wenn jemand sein eigenes Hundefutter frisst, und sie ist es wert, sich zu merken, wenn Leute sagen „1.0 heißt ausgereift".

Cloudflares Migrations-Post veröffentlichte außerdem ihre eigene Editor-Bug-Liste: Custom-HTML-Blöcke waren im Block-Picker schwer zu finden, die Formatierungs-Toolbar scrollte bei langen Posts weg, In-Entity-Editor-Bugs und die Scheduled-Post-Probleme oben. Das sind keine Third-Party-Schmähungen. Das ist der Vendor, der seine eigenen Papercuts öffentlich loggt — für dich als Käufer nützlicher als jede Feature-Matrix.

## EmDash 1.0 und die Plugin-Registry: was geshipt wurde

Zwischen Aprils Beta und Ende-September-1.0 ist die Headline-Änderung eine dezentrale Plugin-Registry, gebaut auf AT Protocol, demselben Protokoll, das Bluesky antreibt. Publisher behalten Ownership, Identität und Release-History in ihren eigenen signierten Records (Merkle Search Trees mit Inclusion Proofs). EmDash fährt einen Default-Katalog, einen Aggregator und einen Workers-AI-Labeler für Moderation, alles Open Source. Das heißt: Keine einzelne Firma kann die History eines Plugins still umschreiben oder einem Publisher die Identität wegnehmen. Wenn der Aggregator-Record und der eigene Record des Publishers auseinanderlaufen, flaggt EmDash es (`AGGREGATOR_RECORD_MISMATCH` kam in 0.37.0), statt mit den Schultern zu zucken.

Install-Time-Verifizierung ist, wo es interessant wird. EmDash prüft Checksums (base32-Multibase-sha2-256, Pflicht seit 0.37.0), Paketnamen, Version und Capability-Manifest-Identität. Optionale Sigstore- und SLSA-Provenance wird verifiziert, wenn vorhanden. Delegated Releases laufen über GitHub OIDC mit Workflow-Pinning via `releases.emdashcms.com`, und Publisher-Onboarding nutzt einen Browser-Approval-Schritt. Stell dir den Install-Dialog wie den Berechtigungs-Prompt eines Mobile-App-Stores vor: Du siehst, was das Plugin kann, bevor du es genehmigst.

**Der wirklich neue Teil**

CMS-Plugin-Ökosysteme waren historisch ein Vertrauens-Müllcontainer. Cloudflares eigener Launch-Post für EmDash zitierte, dass 96 % der Sicherheitsprobleme von WordPress-Sites aus Plugins stammen. Eine signierte, dezentrale Registry mit Capability-Review zur Installationszeit ist ungewöhnlich ernst für diesen Bereich. Es ist ein Gegenargument, kein Beweis, dass das Ökosystem sicher wachsen wird.

Das Ökosystem bei 1.0 ist klein, aber nicht mehr leer: Lexington Themes shippt 44 Astro-Themes mit EmDash-Varianten, Urumi ist das erste eCommerce-Plugin, und Empress zielt auf Multi-Brand-Flotten. Bezahlte Plugins sind noch nicht in der Registry (Cloudflare schaut dafür auf Atproto Spaces Alpha). Und eine Einschränkung, die ich für dich nicht auflösen kann: Die exakte Zahl installierbarer sandboxed Plugins im Katalog gerade jetzt braucht einen Live-Check im Admin. Auf diese Zahl steht und fällt das Ökosystem-Argument. Alles andere in 1.0 ist die langweilige Art von Reife: der WordPress-Importer (WXR, REST-API, WordPress.com via ein EmDash-Exporter-Plugin mit Application Passwords), Lokalisierung mit Übersetzungsgruppen, Revisions, Drafts, Trash, FTS5-Suche, Audit-Log und das Agent-Tooling (MCP, `npx emdash types`, Agent-Skills).

### Sandboxed Plugins und Capability-Manifeste

EmDash hat zwei Plugin-Formate. **Native Plugins** gehen in `plugins: []` und laufen in-process mit vollem Host-Zugriff. Das ist für First-Party- oder voll vertrauten Code: Forms, Embeds, SEO, Audit-Log, Cloudflare-E-Mail.

**Sandboxed Plugins** sind die interessanten. Sie werden in `sandboxed: []` deklariert oder aus der Registry installiert, und sie shippen ein Capability-Manifest wie `capabilities: ["content:read", "email:send"]`. Der Admin genehmigt diese Capabilities bei der Installation. Das eigene Beispiel der Docs ist die richtige Denkweise: Ein Plugin, das Artikel für die Suche indexiert, kann Inhalte lesen und einen Search-Service aufrufen und kann keine Artikel editieren oder andere Hosts kontaktieren. Hooks wie `content:afterSave` laufen in einer isolierten Runtime nur mit privatem Storage und ohne Netzwerkzugriff, es sei denn, exakte Hostnames wurden deklariert.

Die Durchsetzung ist physisch, nicht auf Ehrenwort. Auf Cloudflare ist jedes Plugin ein Dynamic Worker via Worker Loader. Auf Node.js ist es ein `workerd`-Kindprozess, Cloudflares eigene Runtime, die auf deiner Box läuft. Limits sind fixiert ohne Config-Knob: 50ms CPU und 10 Subrequests (nur Cloudflare), 128MB Memory, 30s Wall Time auf beiden. Ein Hook-Timeout wird geloggt, und der Request läuft ohne das Plugin weiter. Ein Route-Timeout lässt den Aufrufer fehlschlagen.

`sandbox: false` lässt sandboxed Plugins in-process laufen. Nur zum Debuggen. Es verweigert den Start auf Cloudflare Workers.

### EmDash Build: der AI-Site-Builder in Alpha

EmDash Build ist ein Open-Source-Alpha-AI-Site-Builder (Demo auf `build.emdashcms.com`): ein Cloudflare-Sandbox-Container pro Projekt, das Agents SDK, Änderungen getrackt als Git-Commits, Publishing in Workers for Platforms. Beobachte es. Bau noch keine Kundenarbeit darauf.

## Für wen EmDash ist (und wann die eigenen Docs raten, etwas anderes zu wählen)

Credit, wo Credit gebührt: EmDashs Docs sind ungewöhnlich ehrlich darüber, wer das nicht nutzen sollte. Die „good fit"-Checkliste verlangt, dass alle vier dieser Punkte zutreffen:

- Die Website ist mit Astro gebaut

- Redakteure müssen Inhalte verwalten, ohne Repo-Dateien zu editieren

- Du willst CMS und Website in einer Anwendung und einem Deployment

- Du kannst eine Datenbank und Medien-Storage neben der Site betreiben

Wenn du nicht alle vier abhaken kannst, hör hier auf. Die „reasons to choose another approach" der Docs sind fast wörtlich: Das Projekt ist nicht Astro; alle Inhalte müssen im Source-Repo bleiben; mehrere unabhängige Frontends brauchen ein CMS, das unabhängig deployt; oder du willst die Ops-Last nicht. Der letzte Punkt steht dort in klaren Worten: Das Team ist verantwortlich für die Datenbank, Medien-Storage, Backups, Upgrades und die Anwendung, die das Admin-Panel serviert.

Das greift dem Einwand Nummer eins auf Reddit vor („you need to manage a database to use it"). Ja. Musst du. Die Docs stimmen zu und sagen git-basierten CMS-Usern, sie sollen dateibasierte Collections nutzen.

Die eigene Vergleichstabelle der Docs lohnt sich, für dein Entscheidungsmeeting zu klauen:

### EmDash

Redakteure arbeiten in einer Web-Admin-UI. Seiten laden Inhalte zur Request-Zeit via Live Content Collections (oder zur Build-Zeit für prerendered Pages). Das Content-Modell lebt in der Datenbank, versioniert durch die App. Dein Team betreibt die Datenbank, Medien-Storage, Backups, Upgrades und die App selbst. Site und CMS shippen zusammen ohne Release-Trennung.

### Dateibasierte Astro-Collections

Redakteure arbeiten in Git oder einer git-gestützten UI. Seiten laden Inhalte zur Build-Zeit. Das Content-Modell lebt in Markdown-/MDX-Dateien im Repo. Dein Team betreibt die Build-Pipeline und das Repo. Inhaltsänderungen sind Commits und Rebuilds.

### Separates Headless-CMS

Redakteure arbeiten in einem Third-Party-Admin. Seiten laden Inhalte zur Build- oder Request-Zeit via API. Das Content-Modell lebt in der Datenbank des Vendors. Dein Team betreibt das Frontend plus die Integration; der Vendor fährt das CMS. CMS und Frontends deployen unabhängig mit voller Release-Trennung.

## EmDash vs. WordPress: was die April-Kritiker richtig und falsch lagen

Die April-Takes sind interessant gealtert. Hier die Abrechnung, nochmal gegen sechs Monate Evidenz gehalten.

Zum Kontext, wogegen EmDash antritt: WordPress betreibt immer noch einen riesigen Teil des Webs, mit 60k+ Plugins und einem Theme-Markt, den 2026 niemand matcht. Cloudflares Launch-Winkel war Security und Architektur: Es zitierte, dass 96 % der Sicherheitsprobleme von WordPress-Sites aus Plugins stammen, und positionierte sandboxed Plugins plus Passkeys als Antwort. Die Community-Reaktion spaltete sich entlang vorhersehbarer Linien. Die WordPress-Crowd auf Reddit nannte es ein „vibe coded CMS that barely works" und notierte das Ökosystem-Catch-22 (in einem Thread sagte jemand, sein Team hätte es gedemot und ein „hard no" gegeben). Die Astro-Crowd war interessiert. Beide bewerteten eine Beta.

| Kritiker | April-Claim | Was die 1.0-Evidenz sagt | Urteil |
|---|---|---|---|
| Matt Mullenweg | „Uncanny valley"-UI, TinyMCE-Rückschritt, schlug Gutenberg vor; lobte Agent Skills als „amazing" | TipTap ist immer noch nicht Gutenberg. Cloudflares eigener Migrations-Post loggte Editor-Beschwerden: Custom-HTML-Blöcke schwer zu finden, Formatierungs-Toolbar scrollt bei langen Posts weg | Halb richtig. Der Editor ist besser als v0.1, immer noch jung |
| WPJohnny | „Almost zero"-Marktanteils-Bedrohung; Serverless-Pitch „not relatable for 99.99%" der WP-Anwendungsfälle | 126k npm-Downloads/Monat und der Cloudflare-Blog in Produktion sind nicht null. Aber Marktanteils-Realismus steht | Recht zum 2026er-Anteil, falsch zur Trajektorie |
| Maciek Palmowski | Mag das Sandboxing und das AI-first-Design, aber „does it solve the right problem?" für jemanden, der auf Markdown glücklich ist | Sein Punkt überlebt: EmDash fügt Datenbank-Ops hinzu, die Markdown nicht hat | Recht für Markdown-User, was die Docs inzwischen zugeben |
| CMSWire | „Right architecture, empty ecosystem" | Lexington (44 Themes), Urumi, Empress und eine echte Plugin-Registry. Der Katalog ist neben 60k+ WP-Plugins immer noch winzig | Immer noch das Kernrisiko, weniger akut als im April |

Die Lock-in-Frage verdient eine gerade Antwort, da Mullenweg sie aufwarf. EmDash ist MIT. Die Adapter sind portabel: D1, SQLite, libSQL, Postgres, R2, jede S3-API, lokale Disk. Die Node-Deploy-Docs sind nicht Cloudflare-first. Das Lock-in-Risiko ist Gravitation (Ökosystem, Feinschliff, wer Bugs am schnellsten fixt), nicht Lizenzierung. Mullenweg schrieb außerdem „I'd be surprised if this doesn't get tens of thousands of sites on it"; WPJohnny sagte, die Bedrohung sei „almost zero". Sechs Monate Downloaddaten liegen zwischen diesen beiden Claims. Und auf der WordPress-Seite des Zauns ist genau das die Kosten- und Ops-Rechnung, für die [unser Astro-vs.-WordPress-Kosten-und-Ops-Breakdown](/astro-vs-wordpress/) da ist.

Noch ein WordPress-Vergleich, der zählt, wenn du migrierst: Der Importer ist real, aber begrenzt. Posts, Pages, Media, Taxonomies und Custom Post Types kommen rüber (CPTs mappen auf Collections, Gutenberg-Inhalte konvertieren zu Portable Text). Dein Theme kommt nicht rüber. Custom-Plugin-Verhalten kommt nicht rüber. Die Docs sagen das unverblümt. Budgetiere einen Rebuild der Präsentationsschicht, nicht nur ein Export-Import.

**Das Catch-22 ist immer noch real**

Keine Plugins ohne User, keine User ohne Plugins. Die 1.0-Registry ist das Gegenargument zu dieser Schleife, kein Beweis, dass sie gelöst ist. Wenn dein Projekt 2026 einen ausgereiften Plugin-Store braucht, gewinnt WordPress immer noch, und so zu tun, als wäre es anders, verschwendet deine Zeit.

## EmDash deployen: Cloudflare Workers vs. Self-Hosted auf einem VPS

Beide Deploy-Pfade sind offiziell dokumentiert, und beide shippen Admin plus API plus MCP als eine Einheit. Das Operator-Framing ist einfach. Der Cloudflare-Pfad ist die wenigsten Server und die meiste Plattform-Kopplung, mit sandboxed Plugins hinter Workers Paid gated. Der VPS-Pfad ist langweilige Ownership: Datenbank, Backups und Upgrades gehören dir, auf einer Box, die du kontrollierst. Unten beide, mit den Configs, die du brauchst.

![EmDash-CMS-Deploy-Pfade im Vergleich: Cloudflare Workers mit D1 und R2 gegenüber Self-Hosted-Node.js mit SQLite und S3-Backups auf einem VPS](@assets/images/26/09/emdash-deploy-paths.svg)

### Der Cloudflare-Pfad: Workers + D1 + R2 (und wo Workers Paid Pflicht ist)

Schnellster Happy Path: den „Deploy to Cloudflare"-Button auf dem `blog-cloudflare`-Template im `emdash-cms/templates`-Repo drücken (das volle Set ist blog, marketing, portfolio, starter und blank, jedes mit einer Cloudflare- und einer Node-Variante). Wrangler legt die D1-Datenbank und den R2-Bucket beim ersten Deploy an, und Migrationen werden beim ersten Request automatisch im Default-`auto`-Modus angewendet. Templates lassen das Worker-Loader-Binding auskommentiert, weshalb neue Projekte per Default auf dem Free Plan deployen.

Wenn du es selbst verdrahtest, sehen die Essentials so aus:

```jsonc
// wrangler.jsonc (essentials)
{
  "name": "my-emdash-site",
  "main": "./src/worker.ts",
  "compatibility_date": "2026-02-24",
  "compatibility_flags": ["nodejs_compat"],
  "d1_databases": [{ "binding": "DB", "database_name": "my-emdash-site" }],
  "r2_buckets": [{ "binding": "MEDIA", "bucket_name": "my-emdash-media" }],
  "worker_loaders": [{ "binding": "LOADER" }],   // only for sandboxed plugins (Workers Paid)
  "triggers": { "crons": ["* * * * *"] },        // publishing, plugin tasks, backups, maintenance
  "placement": { "mode": "targeted", "region": "..." } // near the D1 primary
}
```

```ts
// astro.config.mjs (Cloudflare)
import cloudflare from "@astrojs/cloudflare";
import react from "@astrojs/react";                 // REQUIRED - admin UI is React
import emdash from "emdash/astro";
import { d1, r2, sandbox, kvCache } from "@emdash-cms/cloudflare";

export default defineConfig({
  output: "server",
  adapter: cloudflare(),
  integrations: [react(), emdash({
    database: d1({ binding: "DB" }),
    storage: r2({ binding: "MEDIA" }),
    sandboxRunner: sandbox(),                 // omit + drop LOADER to stay on the free plan
    objectCache: kvCache({ binding: "CACHE" }) // optional KV object cache
  })]
});
```

```ts
// src/worker.ts
import handler, { createScheduledHandler, PluginBridge } from "@emdash-cms/cloudflare/worker";
export { PluginBridge };
export default { ...handler, scheduled: createScheduledHandler() } satisfies ExportedHandler;
```

Deploye mit `pnpm build && pnpm wrangler deploy`. Cloudflare-spezifische Extras in einem Durchgang: Targeted Placement nahe dem D1-Primary (nicht mit D1-Read-Replicas kombinieren, und `session` auf seinem Default `"disabled"` lassen), Workers Cache via den `cacheCloudflare()`-Provider mit `routeRules`, Image-Transforms über das `IMAGES`-Binding (abgerechnet als Cloudflare Images: 5.000 unique Transformations/Monat gratis auf dem Free Plan, danach schlagen neue mit Fehler `9422` fehl), Cloudflare-Access-SSO mit Role Mapping (Secret via `wrangler secret put CF_ACCESS_AUDIENCE`) und E-Mail via das Cloudflare-Email-Plugin mit einem `send_email`-Binding. Der letzte Punkt zählt: Magic Links und Einladungen schlagen mit „Email is not configured" fehl, bis du es eingerichtet hast, und passwordless Auth ist der Default-Flow.

**Wo Workers Paid Pflicht ist**

Sandboxed Plugins und Marketplace-Installs brauchen das Worker-Loader-Binding, das einen Workers-Paid-Plan erfordert (üblicherweise mit 5 $/Monat zitiert, verifiziere die aktuellen Preise, bevor du budgetierst). Ohne es warnt der Build „Sandboxed plugins are disabled because wrangler.jsonc has no LOADER Worker Loader binding", und Runtime-Installs schlagen mit `SANDBOX_NOT_AVAILABLE` fehl. Die Site läuft sonst normal, was genau der Grund ist, warum es Leute übersehen.

Verifiziere, bevor du es fertig nennst:

1. `pnpm wrangler tail` und bestätige, dass der Scheduled Handler tickt (der `* * * * *`-Cron).
2. Öffne `/_emdash/admin`, log dich ein und prüfe, dass das Dashboard lädt.
3. Veröffentliche einen Draft und bestätige, dass die öffentliche Seite beim nächsten Request aktualisiert.

Wenn du allgemein auf Workers baust (mehr als nur EmDash), deckt unser Guide zu [Self-Hosted-Apps auf Cloudflare Workers](/de/self-hosted-apps-cloudflare-workers/) die Plattform-Muster ab, auf denen dieser Stack sitzt.

### EmDash auf Node.js selbst hosten: SQLite, Docker und S3-Backups

Das ist der Bitdoze-Home-Turf-Pfad: Node.js standalone, SQLite auf einem Volume, S3-kompatible Medien, Docker und deine normale Backup-Routine. Jede Hetzner-Klasse-Box im Bereich 4 bis 5 Euro im Monat fährt eine EmDash-Site auf Blog-Niveau komfortabel. Das ist in der Praxis ein [Hetzner-Cloud-VPS](https://go.bitdoze.com/hetzner), oder eine Budget-KVM-Box wie [Hostinger VPS](https://go.bitdoze.com/hostinger-vps), wenn du andere Regionen willst oder deren Panel bevorzugst.

Was du zuerst brauchst:

- Node.js &gt;= 22.16 (oder Docker mit einem node:22-Image)

- Ein VPS mit 1 bis 2 GB RAM und einem DNS-Record, der darauf zeigt

- Optional: ein S3-kompatibler Bucket (R2, Backblaze B2, MinIO) für Medien

- Secrets aus npx emdash secrets generate (EMDASH_ENCRYPTION_KEY und Freunde)

Die Node-Config ist kürzer als die Cloudflare-Variante:

```ts
// astro.config.mjs (Node.js)
import node from "@astrojs/node";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite } from "emdash/db";   // also: libsql, postgres adapters

export default defineConfig({
  output: "server",
  adapter: node({ mode: "standalone" }),
  integrations: [emdash({
    database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
    storage: local({ directory: "./data/uploads", baseUrl: "/_emdash/api/media/file" }),
    // storage: s3() for S3-compatible media (R2, AWS S3, any S3 API)
    sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox" // needs @emdash-cms/sandbox-workerd + workerd
  })]
});
```

Fahr es mit `node --env-file=.env ./dist/server/entry.mjs` (Port 4321 per Default, `HOST`- und `PORT`-Env-Vars werden beachtet). Der Standalone-Entry lädt `.env` nicht automatisch. `--env-file` zu vergessen ist der häufigste First-Run-Fehler hier.

Die offiziellen Docs shippen ein Dockerfile und docker-compose.yaml (node:22-alpine Multi-Stage, Named Volume für `/app/data`), das direkt in ein Dokploy-artiges Deploy fällt. Auf die Essentials angepasst sieht die Compose-Seite so aus:

```yaml
# adapted from the official docs.emdashcms.com/deployment/nodejs/ compose file
services:
  emdash:
    build: .
    ports:
      - "4321:4321"
    env_file: .env
    volumes:
      - emdash-data:/app/data   # SQLite db + local uploads live here
    restart: unless-stopped

volumes:
  emdash-data:
```

Eine Docker-Falle: `workerd` ist eine plattformspezifische Binary, die via optional Dependencies installiert wird. Installiere sie in Multi-Stage-Builds auf derselben Plattform wie die Runtime-Stage mit optional Deps an, dann verifiziere:

```bash
./node_modules/.bin/workerd --version
```

Env-Variablen, die man kennen sollte: `DATABASE_PATH`, `HOST`, `PORT`, `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_REGION`, `S3_PUBLIC_URL`, `EMDASH_ENCRYPTION_KEY` und optional `EMDASH_PREVIEW_SECRET`, `EMDASH_AUTH_SECRET`, `EMDASH_IP_SALT`, `EMDASH_WORKERD_PASSTHROUGH_ENV`. Lies Secrets niemals aus `import.meta.env`; Vite inlined sie zur Build-Zeit ins Client-Bundle.

Backup-Lage: Halte SQLite auf einem Named Volume, Medien auf S3, und denk dran, dass automatische JSON-Snapshots unter `backups/` im selben Storage-Backend leben. Stoppe den Prozess, bevor du die DB-Datei ersetzt — das ist die eigene Restore-Prozedur der Docs. Halte eine Recovery-Kopie von `EMDASH_ENCRYPTION_KEY` außerhalb deiner Datenbank-Backups, sonst sind wiederhergestellte Plugin-Einstellungen unlesbar. Rollback ist das, was dein Volume-Snapshot plus Key-Kopie hergibt; es gibt kein EmDash-natives Point-in-Time-Recovery, das dich rettet.

Für Panel-basierte Ops statt rohem systemd kannst du [Node.js-Apps auf CloudPanel hosten](/install-cloudpanel-host-nodejs/) (wir fahren dort Strapi 5), oder folge [wie man Astro auf einem VPS mit CloudPanel deployt](/deploy-astro-on-vps/), sobald das CMS selbst läuft. Wenn du eine One-Click-Docker-Compose-Route willst, passt [Coolify, die Self-Hosted-PaaS](/coolify-v5-self-hosted-paas-review/), und [Coolify vs. Dokploy vs. Kamal im Vergleich](/coolify-vs-dokploy-vs-kamal-2/) ist das Pick-the-Tool-Stück. Für die Medienseite deckt [S3-kompatiblen Storage auf einem VPS mounten](/s3-bucket-filesystem-vps/) die Bucket-as-Filesystem-Optionen ab.

Verify-Block, der Reihe nach, bevor du DNS darauf zeigst:

1. `npx emdash migrate --check` meldet clean.
2. Eine öffentliche Seite liefert 200 mit erwartetem Inhalt.
3. Du kannst dich unter `/_emdash/admin` einloggen.
4. Media-Upload-, Retrieve- und Delete-Roundtrip funktioniert.
5. Ein Draft publisht und die öffentliche Seite aktualisiert.
6. Ein Sandboxed-Plugin-Aufruf funktioniert (falls du welche nutzt).
7. Scheduler-Ticks tauchen in den Prozess-Logs auf.

### Kostenrechnung: Free-Tier-Workers vs. ein 4-Euro-VPS

Größenordnungen, Stand September 2026. Behandle sie nicht als Angebote.

| Pfad | Monatliche Kosten | Was du bekommst | Was dir gehört |
|---|---|---|---|
| Workers Free | 0 $ | Basis-Site (Templates lassen das LOADER-Binding auskommentiert), D1-/R2-/KV-Gratis-Kontingente | Keine sandboxed Plugins; Images-Transforms cap bei 5k unique/Monat; SSR- + D1-Request-Ökonomie beobachten |
| Workers Paid | ~5 $/Monat (verifizieren) | Worker Loader für sandboxed Plugins und Marketplace-Installs | Dasselbe, plus Plattform-Kopplung |
| VPS (Hetzner-Klasse) | ~4–5 EUR/Monat | Volle Kontrolle, SQLite + S3-Medien, workerd-Child, Docker | DB-/Medien-Backups, Upgrades, Uptime, Security-Patches |

Zwei Notizen, die die Tabelle versteckt. Das Paket ist schwer: 23 MB unpacked und 2.489 Dateien, Worker-Cold-Starts und Container-Image-Größen sind also nicht trivial. Und der Cloudflare-Blog brauchte KV-Object-Cache plus Hyperdrive plus Workers Cache, um seine Zahlen zu erreichen. Normale Sites werden das nicht.

Eine dritte Notiz, da Free-Tier-Ökonomie die übliche Frage ist: EmDash ist server-gerendert, jeder ungecachte Page-Hit macht also D1-Roundtrips. Ein Low-Traffic-Blog sitzt komfortabel innerhalb der Gratis-Kontingente. Eine vielbesuchte Marketing-Site sollte Requests modellieren, statt anzunehmen, „scales to zero" heiße gratis. Der Cloudflare-Blog erreichte ~70 % Cache-Abdeckung erst nach dem Hinzufügen der Workers-Cache-Schicht; deine Defaults werden niedriger liegen.

**Preise vor der Budgetierung nochmal prüfen**

EmDashs Docs zitieren Plan-Anforderungen, keine Dollarzahlen. Verifiziere Workers-Paid- und Cloudflare-Images-Preise auf Cloudflares Pricing-Seite, bevor du Zahlen in ein Kunden-Angebot schreibst.

Wenn du Daten willst, bevor du dich auf eine Box festlegst, ist [wie man Cloud-Server vor dem Commitment benchmarkt](/benchmark-cloud-servers/) der YABS-Workflow, den ich nutze.

## Ops-Fallen, auf die du stoßen wirst

Das ist die Troubleshooting-Schicht, die kein April-Review hatte. Alles unten kommt aus EmDashs eigenen Deployment- und Troubleshooting-Docs plus dem Migrations-Post-Mortem. Die Docs sind ehrlich darüber. Der Failure Mode sind Operatoren, die sie nicht lesen.

### workerd auf Node: Crash-Loops und das 10-Sekunden-Startup-Fenster

Auf Node.js laufen sandboxed Plugins in Cloudflares `workerd`-Runtime als Kindprozess. Das ist ein echter Prozess mit echter Crash-Semantik. Der Start muss innerhalb von 10 Sekunden antworten. Ein unerwarteter Exit triggert einen Restart mit 1-bis-30-Sekunden-doubling-Backoff. Und hier die scharfe Kante: 5 Crashes in 60 Sekunden und der Runner gibt auf, bis du den Server neu startest. Die Logzeile ist unverblümt: „workerd crashed 5 times in 60 seconds, giving up." Jeder sandboxed Hook und jede Route schlägt von da an fehl, während die Site weiterserviert.

Der Kindprozess bekommt außerdem eine abgespeckte Umgebung: nur `PATH`, `HOME`, `TMPDIR`, `TMP`, `TEMP`, `LANG`, `LC_ALL`. Secrets lecken nicht in die Sandbox. Erweitere sie mit `EMDASH_WORKERD_PASSTHROUGH_ENV`, wenn ein Plugin wirklich mehr braucht.

Wenn Sandboxed-Plugin-Features tot wirken, während die Site weiterserviert, hat der workerd-Crash-Loop seine Retries erschöpft. Starte den App-Prozess neu, dann prüfe `./node_modules/.bin/workerd --version` und bestätige, dass die Binary zu deiner Container-Plattform passt. Wenn die Sandbox stattdessen beim Start innerhalb von Docker crasht, wurde die workerd-Binary wahrscheinlich für die falsche Plattform gebaut: Ein Multi-Stage-Build installierte sie auf der Plattform des Builders. Reinstalliere sie mit optional Deps an auf der Plattform der Runtime-Stage.

### EMDASH_ENCRYPTION_KEY-Rotation und Backup-Fallen

Setze `EMDASH_ENCRYPTION_KEY`, bevor du das erste Plugin-Secret speicherst. Generiere es mit `npx emdash secrets generate`. Halte eine Recovery-Kopie außerhalb deiner D1- oder SQLite-Backups, weil ein Restore der Datenbank ohne den Key Plugin-Einstellungen unlesbar lässt.

Rotation ist manuell und leicht gruselig: generiere einen neuen Key, halte die alten Keys komma-separiert gelistet, bis jedes Plugin-Secret unter dem neuen Key neu gespeichert wurde, dann lass die alten fallen. EmDash meldet nicht, welche Key-IDs noch in Benutzung sind. Das ist eine dokumentierte Lücke, kein Bug, den du dir einbildest.

**Behandle EMDASH_ENCRYPTION_KEY wie ein Produktions-Secret**

Lagere es in deinem Passwort-Manager oder Secret Store. Shippe niemals ein Datenbank-Backup ohne eine separate Kopie seines Keys. Und lies Secrets niemals aus `import.meta.env` in deiner Config: Vite inlined Env-Variablen zur Build-Zeit ins Bundle, was eine Config-Bequemlichkeit in einen Leak-Vektor verwandelt.

### Workers Cache serviert eingeloggten Redakteuren stale Pages

Responses ohne expliziten `Cache-Control`-Header werden über die RFC-9111-Heuristik grob 2 Stunden gecacht. Setze explizite Header auf jeder Custom Route: `private, no-store` für alles Session-abhängige.

**Redakteure können die gecachte anonyme Seite bekommen**

Das klassische Symptom: Ein eingeloggter Redakteur öffnet eine öffentliche Seite und bekommt die gecachte anonyme Variante, ohne Visual-Editing-Toolbar, bis der Cache abläuft. Admin- und API-Responses senden schon `private, no-store`; deine Custom Routes nicht. Setze explizite Header auf jeder Route, die du hinzufügst.

Wenn du Edge-Caching ohne Workers Cache willst, können Self-Hoster Statisches und Medien mit einem CDN wie [Bunny.net](https://go.bitdoze.com/bunny) fronten und Origin-Caching explizit halten.

**R2-publicUrl exponiert alles**

Wenn du `publicUrl` auf einem öffentlichen R2-Bucket setzt, ist jedes Objekt darin erreichbar, inklusive der automatischen JSON-Backups unter `backups/`. Halte Backups in einem privaten Pfad oder einem separaten Bucket, und sieh dir [S3-kompatiblen Storage auf einem VPS mounten](/s3-bucket-filesystem-vps/) an, wenn du den Bucket getrennt von der App behandelt willst.

### Warum der Health-Endpoint lügt

Die Docs schlagen vor, `src/pages/health.ts` mit einem 200 hinzuzufügen. Mach es, aber verstehe das Limit: Ein 200 beweist nur, dass Astro Requests serviert. Datenbankgesundheit, Storage-Gesundheit, Migrationen und die Sandbox sind nicht abgedeckt. Die Docs sagen das explizit.

**Ein grünes /health ist kein Deploy-Gate**

Nutze die Checkliste unten als dein Deploy-Gate. `/health` ist eine Liveness-Probe, nichts mehr.

- Eine öffentliche Seite anfragen und den erwarteten Inhalt bestätigen

- npx emdash migrate --check meldet clean

- Draft-Publish-Roundtrip: publishen, öffentliche Seite verifizieren, unpublishen

- Media-Upload-, Retrieve- und Delete-Roundtrip

- Ein Sandboxed Plugin aufrufen (falls du welche fährst)

- Bestätigen, dass der Scheduled Handler feuert: pnpm wrangler tail auf Cloudflare, Prozess-Logs auf Node

### Mehr Fallen, die man kennen sollte

**react() fehlt**

Die Admin-UI ist eine React-App. Die `react()`-Astro-Integration wegzulassen bricht den Admin, selbst auf einer reinen Astro-Site. Es ist die erste Config-Zeile, die du prüfst.

**Migrationen werden beim ersten Request auto-applied**

Der Default-`auto`-Modus fährt Migrationen beim ersten Request nach einem Deploy. Das ist Blast Radius in Produktion. Fahr `npx emdash migrate --check` zuerst in CI — das ist, was die Docs für Pipelines empfehlen.

**Node-Scheduler pausiert mit dem Prozess**

Scheduled Publishing und Plugin-Tasks laufen nur, während ein Prozess oben ist. Halte mindestens einen Prozess laufend. Auf Cloudflare deckt das der `* * * * *`-Cron ab. Und denk dran: Scheduled Posts funktionierten bis v0.19.0 überhaupt nicht.

**Preview-Environments und Version-Pins**

Wrangler-Named-Environments erben keine Bindings; wiederhole jedes Binding in Preview, und zeige Preview niemals auf die Produktions-Datenbank oder den -Bucket. Pinne außerdem `>= 0.37`: Ein D1-Row-Scan-Spike im scheduled Media-Usage-Cleanup (hunderttausende Rows pro Cron-Tick auf großen Sites) wurde in 0.37.0 gefixt.

## Pros und Cons nach 1.0

Worauf läuft dieses EmDash-CMS-Review also hinaus? Acht gepaarte Tradeoffs. Lies die rechte Spalte zweimal, bevor du dich festlegst; dort wohnt die Betriebskosten.

| Pros | Cons |
|---|---|
| Wirklich neuartiges Plugin-Sicherheitsmodell: Capability-Manifeste, Sandbox, jetzt gestützt durch eine signierte dezentrale Registry | Der Plugin- und Theme-Katalog ist winzig gegenüber WordPress' 60k+ Plugins; Ökosystem-Reife ist unbewiesen |
| Echter Produktions-Beweis auf Skala: Cloudflare-Blog serviert bis zu 850 RPS, 5k+-Spitzen, 28k-RPS-DDoS am Edge absorbiert, ~70 % Cache-Trefferquote | Du betreibst eine Datenbank, Medien-Storage, Backups und Upgrades. Die Docs sagen es in klaren Worten |
| Eine deploybare Einheit: Astro-Site + Admin + REST-API + MCP; Live Content Collections heißt, Edits erscheinen beim nächsten Request ohne Rebuild | Astro-only. Content-in-git-User sind explizit nicht die Zielgruppe |
| Agent-nativ ohne Hype-Steuer: MCP in jedem Install, `_rev`-Concurrency seit 0.37.0, Agent-Skills, CLI, WP-Importer | Die Admin-UX reift noch. Aprils Kritiker lagen damit nicht falsch; Cloudflares eigene Migration loggte Editor-Bugs |
| Portable Adapter: D1/SQLite/libSQL/Postgres, R2/S3/lokal; offizieller Docker- und Compose-Pfad für einen günstigen VPS | Die Sandbox-Story ist auf Cloudflare am stärksten (Workers Paid). Auf Node fährst du `workerd`, Cloudflares Runtime, als Kindprozess mit eigener Crash-Semantik |
| Ship-Velocity: ~37 Releases in 6 Monaten, signierte Builds, npm Provenance, 175+ Contributors, MIT | Velocity schneidet in beide Richtungen: Breaking Changes innerhalb von 0.x (die `_rev`-Anforderung landete in 0.37.0) und Docs-Drift (das README sagt noch „beta" und listet 3 Templates, wo das Repo 5 hat) |
| Passkeys-first-Auth, RBAC-Rollen, optionales Cloudflare-Access-SSO | E-Mail ist auf Workers nicht out of the box konfiguriert; Magic Links und Einladungen schlagen fehl, bis du das Email-Plugin und das Binding hinzufügst |
| x402 eingebaut: gratis zu ignorieren, interessant, wenn du Agent-paywallten Content willst | x402 ist nascent (~28k $/Tag ökosystemweit im April), und Scheduled Publishing war bis 0.19.0 kaputt. Early-Days-Risiko ist real |

## Fazit: Wer EmDash nutzen sollte (und wer nicht)

![Entscheidungsflussdiagramm für die EmDash-CMS-Adoption: Astro-Anforderung, Redakteurs-Bedürfnisse, Bereitschaft zu Datenbank-Ops und Cloudflare-vs.-VPS-Deploy-Wahl](@assets/images/26/09/emdash-decision-flow.svg)

**Agentur.** Die glaubwürdigste neue Plattform-Build-Wette seit Jahren: Templates für die Übergabe, sandboxed Plugins als Support-Blast-Radius-Kontrolle, Workers for Platforms und EmDash Build als White-Label-Site-Maschinerie. Aber wähl es für neue Astro-Builds, bei denen du das Theme kontrollierst, nicht für Kunden, die den WordPress-Plugin-Store verlangen. Beobachte die Registry auf Paid Plugins; sie sind noch nicht da. Bedingtes Ja.

**Astro-Entwickler.** Wenn du schon ein datenbankgestütztes CMS auf Astro wolltest, ist das der offensichtliche Default gegenüber einem angedockten SaaS-Headless-CMS. `npx emdash types` plus MCP machen es agent-freundlich, und der Node-+-SQLite-Pfad heißt, Cloudflare ist optional. Wenn du ein Content-in-git-Loyalist bist, wechsle nicht; die Docs stimmen dir zu. Ja, mit diesem Vorbehalt.

**WordPress-Flüchtling.** Der Importpfad ist real: WXR, REST-API oder WordPress.com via das EmDash-Exporter-Plugin mit einem Application Password. Custom Post Types mappen auf Collections, Gutenberg konvertiert zu Portable Text. Passkeys plus RBAC sind ein Security-Upgrade. Aber das Theme und jedes ernsthafte Plugin-Verhalten sind ein Rebuild, der Editor ist TipTap statt Gutenberg, und du akzeptierst Datenbank-Ops. Migriere zuerst eine Low-Stakes-Site. Avulux zog eine Microsite in unter einem Tag mit Agent Skills um; deine 40-Plugin-Site wird das nicht sein. Wenn du entscheidest, dass sich der Rebuild nicht lohnt und auf WordPress bleibst, kannst du die Ops-Seite zumindest an Managed Cloud Hosting wie [Cloudways](https://go.bitdoze.com/cloudways) auslagern. Bedingt.

**Solo-Blogger.** Der ehrliche Vergleich ist EmDash gegen Markdown-in-git. Wenn du nur publishst, bleibt statisches Astro plus Markdown einfacher und billiger: keine Datenbank, kein Admin, kein workerd. EmDash verdient seinen Platz in dem Moment, wo du eine Admin-UI, Scheduled Posts, Media-Management oder Nicht-Dev-Co-Editoren willst. Der free-ish-Cloudflare-Deploy (ohne sandboxed Plugins) oder ein 4-Euro-VPS hält es billig. Ja, aber erst ab dieser Schwelle.

Wohin es geht: EmDash Build Richtung GA, Paid Plugins via Atproto Spaces Alpha, weiter reifender Editor und was immer WordPress als Nächstes tut. Das Fazit dieses EmDash-CMS-Reviews: Empfohlen für Astro-Teams, die ein echtes CMS wollen und bereit sind, eine Datenbank zu besitzen. Noch kein WordPress-Ersatz für Plugin-abhängige Sites. Das ist eine viel bessere Position als die, die es im April hatte.

[Astro noch heute auf einem VPS deployen](/deploy-astro-on-vps/)

## EmDash-CMS-FAQ

**Ist EmDash kostenlos?**

Ja. MIT-lizenziert, Open Source, selbst hostbar. Der Cloudflare Free Tier reicht für eine Basis-Site (die Templates lassen das Worker-Loader-Binding auskommentiert). Sandboxed Plugins brauchen Workers Paid, üblicherweise mit 5 $/Monat zitiert (verifiziere die aktuellen Preise). Der VPS-Pfad kostet, was die Box kostet: 4 bis 5 Euro im Monat sind der realistische Floor.

**Funktioniert EmDash ohne Cloudflare?**

Ja. Node.js mit SQLite, libSQL oder Postgres plus S3- oder lokalem Storage ist ein dokumentierter, First-Class-Deploy-Pfad. Der einzige Cloudflare-Code in diesem Stack ist die Sandbox-Runtime (`workerd`), die als Kindprozess auf deinem Server läuft. Datenbank, Medien, Backups und Upgrades gehören dir.

**Kann es von WordPress importieren?**

Ja, für Inhalte. WXR-Export, REST-API oder WordPress.com via das EmDash-Exporter-Plugin mit einem Application Password. Custom Post Types werden Collections, und Gutenberg-Inhalte konvertieren zu Portable Text. Themes und Custom-Plugin-Verhalten sind ein Rebuild. Die Docs sagen das unverblümt.

**Ist EmDash produktionsreif?**

1.0 plus der Cloudflare-Blog in Produktion (bis zu 850 RPS, 5k+-Spitzen) sagt ja für Teams, die die Ops besitzen. Ökosystem und Admin-UX sind noch jung. Pinne `>= 0.37.x`, fahr die Verify-Checkliste vor Traffic und behandle Scheduled Publishing mit Respekt (es existierte bis 0.19.0 nicht).

**Ist EmDash nur Cloudflare-Lock-in?**

Nein. MIT-Lizenz, portable Adapter (D1/SQLite/libSQL/Postgres, R2/S3/lokal) und Node-Deploy-Docs, die nicht Cloudflare-first sind. Das Lock-in-Risiko ist Ökosystem- und Feinschliff-Gravitation, nicht Lizenzierung. Die Sandbox-Runtime ist Cloudflare-Code, läuft aber auch auf deinem eigenen Server.

Das ist ein Snapshot. Zur Drei-Monats-Marke werde ich die Kataloggröße der Registry, Paid-Plugin-Verfügbarkeit, Editor-Fixes von Cloudflares eigener Migrations-Bug-Liste und ob Templates Astro 7 pinnen nochmal prüfen. Bis dahin decken die internen Links oben die breiteren Entscheidungen ab: CMS-Wahl für Astro, Astro-vs.-WordPress-Ökonomie und die Self-Hosting-Pfade auf Workers wie auf VPS.

[Headless-CMS-Optionen für Astro vergleichen](/best-headless-cms-for-astro/)