What is EmDash
A CMS announced by Cloudflare as the spiritual successor to WordPress.
It's a full-stack CMS with a modern architecture using Cloudflare resources (D1/R2/Workers) + Astro—truly the Cloudflare ecosystem CMS!
As an experiment, I migrated a blog previously built with microCMS to EmDash.
The migrated site → Yuru Log
For now it's still using the default theme since it's an experimental site. I'll apply custom styling later.
Setup workflow
1. Create a project
Run npm create emdash@latest. The interactive prompt will ask you questions—just select your preferences.
2. Create Cloudflare resources
You can easily set up databases and storage like this, and deployment is simple too.
npx wrangler login
npx wrangler d1 create my-site
npx wrangler r2 bucket create my-site-media
npm run build && npm run deploy3. Local development
Run npx emdash dev to start your local environment. Access the admin panel at http://localhost:4321/_emdash/admin to complete setup.
4. Deployment and Initial Configuration
Deploy to Workers with npx wrangler deploy, and your site will be live at https://[name].workers.dev.
Since the local and remote databases are separate, you'll need to complete the initial setup (create an admin account) on the remote admin panel as well.
By connecting your GitHub repository, you can enable automatic deployment on push (Cloudflare dashboard → Workers → Settings → Build → Connect to Git repository).
5. Migrating Content from microCMS
We created a migration script to fetch all articles from the microCMS API, then imported them using the EmDash CLI content create command.
Key Points
- Convert microCMS rich editor content (HTML) to Markdown during migration
- Initially migrate images with external URLs, then upload them to R2 and update references
- Use
npx emdash content createinstead ofnpx emdash seed(seed doesn't create revisions, so articles won't display)
Trying it out for real
It's a best-of-both-worlds CMS that combines the ease of setup and implementation you get with a headless CMS and the convenience of controlling everything end-to-end that you get with a full-stack CMS.
What I really liked is that it's Astro-based, so you can leverage your existing knowledge as-is. It seemed like a good fit for small to medium-sized blogs.
However, since the Astro Cloudflare adapter doesn't support the Cache API yet, pages are being generated from D1 on every request, so the speed is slower than I'd like. We'll either need to wait for support or implement custom caching.
Since it's still in beta,
- Draft preview doesn't work by default (more on this below)
- Center and right alignment aren't reflected in the WYSIWYG editor
- Relative paths cause errors when editing items in Menus
- Custom fields can't be reordered
- Users can't be invited
and a few other quirks (as of v0.1.0).
Real-world project adoption still seems like it's a ways off.
About draft preview
The edit screen has a "Preview draft" button, but it's not possible to preview articles in draft status.
EmDash has a preview mechanism built in, but it appears to be disabled by default, requiring the following steps.
- Set an arbitrary secret key in the environment variable
PREVIEW_SECRET(can be generated withnpx emdash auth secret) - Use
verifyPreviewTokenon the article page to retrieve drafts
import { getEmDashEntry, verifyPreviewToken } from "emdash";
const preview = await verifyPreviewToken({
url: Astro.url,
secret: import.meta.env.PREVIEW_SECRET,
});
const { entry, isPreview } = await getEmDashEntry("posts", slug, { preview });With this, you can now view draft articles from the "Preview draft" button in the admin panel.
Summary
This time I implemented it as a full-stack setup following the standard approach, but it looks like a headless CMS-style workflow is also possible where you fetch articles and build them with SSG, so I'd like to try that approach next.
Still in beta, just released. I'm really excited to see how it evolves!
A "master of technique" who jumped from DTP into the web world and, before he knew it, mastered markup, frontend, direction, and accessibility. Active across multiple domains since Liberogic's early days, he's now a walking encyclopedia within the company. Recently, he's been diving deep into prompt-driven efficiency optimization, wondering "Can we rely more on AI for accessibility compliance?" Both his technology and thinking continue to evolve.
Futa
IAAP Certified Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director