emdash README

The project's README from github.com/emdash-cms/emdash. As one markdown file: README.md.

EmDash

A full-stack TypeScript CMS built on Astro and Cloudflare. EmDash takes the ideas that made WordPress dominant -- extensibility, admin UX, a plugin ecosystem -- and rebuilds them on serverless, type-safe foundations. Plugins run in sandboxed Worker isolates, solving the fundamental security problem with WordPress's plugin architecture.

Get Started

[!IMPORTANT] EmDash depends on Dynamic Workers to run secure sandboxed plugins. Dynamic Workers are currently only available on paid accounts. Upgrade your account (starting at $5/mo) or comment out the worker_loaders block of your wrangler.jsonc configuration file to disable plugins.

npm create emdash@latest

Or deploy directly to your Cloudflare account:

Deploy to Cloudflare

EmDash runs on Cloudflare (D1 + R2 + Workers) or any Node.js server with SQLite. No PHP, no separate hosting tier -- just deploy your Astro site.

Templates

EmDash ships with three starter templates:

Blog

Blog template

A classic blog with sidebar widgets, search, and RSS.

  • Categories & tags
  • Full-text search
  • Comment-ready
  • RSS feed
  • Dark / light mode

Marketing

Marketing template

A conversion-focused landing page with pricing and contact form.

  • Hero with CTAs
  • Feature grid
  • Pricing cards
  • FAQ and contact form
  • Dark / light mode

Portfolio

Portfolio template

A visual portfolio for showcasing creative work.

  • Project grid
  • Tag filtering
  • Case study pages
  • RSS feed
  • Dark / light mode

Why EmDash?

WordPress was built for a different era. Running WordPress today means managing PHP alongside JavaScript, layering caches to get acceptable performance, and knowing that 96% of WordPress security vulnerabilities come from plugins. EmDash is what WordPress would look like if you started from scratch with today's tools.

Sandboxed plugins. WordPress plugins have full access to the database, filesystem, and user data. A single vulnerable plugin can compromise the entire site. EmDash plugins run in isolated Worker sandboxes via Dynamic Worker Loaders, each with a declared capability manifest. A plugin that requests read:content and email:send can do exactly that and nothing else.

export default () =>
	definePlugin({
		id: "notify-on-publish",
		capabilities: ["read:content", "email:send"],
		hooks: {
			"content:afterSave": async (event, ctx) => {
				if (event.content.status !== "published") return;
				await ctx.email.send({
					to: "[email protected]",
					subject: `New post: ${event.content.title}`,
				});
			},
		},
	});

Structured content, not serialized HTML. WordPress stores rich text as HTML with metadata embedded in comments -- tying your content to its DOM representation. EmDash uses Portable Text, a structured JSON format that decouples content from presentation. Your content can render as a web page, a mobile app, an email, or an API response without parsing HTML.

Built for agents. EmDash ships with agent skills for building plugins and themes, a CLI that lets agents manage content and schema programmatically, and a built-in MCP server so AI tools like Claude and ChatGPT can interact with your site directly.

Runs anywhere. EmDash uses portable abstractions at every layer -- Kysely for SQL, S3 API for storage -- that work with SQLite, D1, Turso, PostgreSQL, R2, AWS S3, or local files. It runs best on Cloudflare, but it's not locked to it.

How It Works

EmDash is an Astro integration. Add it to your config and you get a complete CMS: admin panel, REST API, authentication, media library, and plugin system.

// astro.config.mjs
import emdash from "emdash/astro";
import { d1 } from "emdash/db";

export default defineConfig({
	integrations: [emdash({ database: d1() })],
});

Content types are defined in the database, not in code. Non-developers create and modify collections through the admin UI. Each collection gets a real SQL table with typed columns. Developers generate TypeScript types from the live schema:

npx emdash types

Query content using Astro's Live Collections -- no rebuilds, no separate API:

---
import { getEmDashCollection } from "emdash";
const { entries: posts } = await getEmDashCollection("posts");
---

{posts.map((post) => <article>{post.data.title}</article>)}

Features

Content -- Blog posts, pages, custom content types. Rich text editing via TipTap with Portable Text storage. Revisions, drafts, scheduled publishing, full-text search (FTS5), inline visual editing.

Admin -- Full admin panel with visual schema builder, media library (drag-drop uploads via signed URLs), navigation menus, taxonomies, widgets, and a WordPress import wizard.

Auth -- Passkey-first (WebAuthn) with OAuth and magic link fallbacks. Role-based access control: Administrator, Editor, Author, Contributor.

Plugins -- definePlugin() API with lifecycle hooks, KV storage, settings, admin pages, dashboard widgets, custom block types, and API routes. Sandboxed execution on Cloudflare via Dynamic Worker Loaders.

Agents -- Skill files for AI-assisted plugin and theme development. CLI for programmatic site management. Built-in MCP server for direct AI tool integration.

WordPress migration -- Import posts, pages, media, and taxonomies from WXR exports, the WordPress REST API, or WordPress.com. Agent skills help port plugins and themes.

Portable Platforms

Layer Cloudflare Also works with
Database D1 SQLite, Turso/libSQL, PostgreSQL
Storage R2 AWS S3, any S3-compatible service, local filesystem
Sessions KV Redis, file-based
Plugins Worker isolates (sandboxed) In-process (safe mode)

Status

EmDash is in beta preview. We welcome contributions, feedback, plugins, themes, and ideas.

npm create emdash@latest

See the documentation for guides, API reference, and plugin development.

Development

This is a pnpm monorepo. To contribute:

git clone https://github.com/emdash-cms/emdash.git && cd emdash
pnpm install
pnpm build

Run the demo (Node.js + SQLite, no Cloudflare account needed):

pnpm --filter emdash-demo seed
pnpm --filter emdash-demo dev

Open the admin at http://localhost:4321/_emdash/admin.

pnpm test          # run all tests
pnpm typecheck     # type check
pnpm lint:quick    # fast lint (< 1s)
pnpm format        # format with oxfmt

See CONTRIBUTING.md for the full contributor guide.

Repository Structure

packages/
  core/           Astro integration, APIs, admin UI, CLI
  auth/           Authentication library
  blocks/         Portable Text block definitions
  cloudflare/     Cloudflare adapter (D1, R2, Worker Loader)
  plugins/        First-party plugins (forms, embeds, SEO, audit-log, etc.)
  create-emdash/  npm create emdash scaffolding
  gutenberg-to-portable-text/  WordPress block converter

templates/        Starter templates (blog, marketing, portfolio, starter, blank)
demos/            Development and example sites
docs/             Documentation site (Starlight)

emdash (emdash-cms/emdash)

Searching Database…

13.8K ·GitHub
这是什么?EmDash 是一个基于 Astro 和 Cloudflare 构建的全栈 TypeScript 内容管理系统,旨在成为 WordPress 的现代化、类型安全的替代品,并带有沙箱化的插件系统。
这是独立应用,还是需要添加到 Astro 项目中的东西?它是一个 Astro 集成,而不是独立应用:把它添加到你的 Astro 配置中,你就能立即获得管理后台、REST API、身份验证、媒体库和插件系统。
我该如何开始使用?你可以直接部署到自己的 Cloudflare 账户,也可以只在 Node.js 上运行基于 SQLite 的本地演示,这种方式完全不需要 Cloudflare 账户。
运行它需要 Cloudflare 账户吗?不需要。EmDash 可以运行在 Cloudflare(D1 + R2 + Workers)上,也可以运行在任何带有 SQLite 的 Node.js 服务器上;但沙箱化插件系统具体依赖 Dynamic Workers,而目前 Dynamic Workers 需要付费的 Cloudflare 套餐。
使用插件有什么限制?要实现安全的插件沙箱,需要付费的 Cloudflare 账户,Dynamic Workers 每月起价 5 美元;如果你不想付费,可以注释掉 wrangler.jsonc 中的 workerloaders 代码块,从而禁用插件。
这只面向开发者,还是非技术人员也能管理内容?内容类型存储在数据库中而不是代码里,因此非开发者可以通过管理界面创建和编辑集合,而开发者则可以根据实时架构生成 TypeScript 类型。
除了 Cloudflare,我还能在其他地方运行它吗?它在 Cloudflare 上运行效果最佳,但并不局限于此——每一层都基于可移植的抽象构建,同样适用于普通 SQLite、Turso、PostgreSQL、AWS S3 和 Redis。
什么是 Portable Text,EmDash 为什么要使用它?它是 EmDash 用来替代 HTML 存储内容的结构化 JSON 格式,因此同一份内容无需解析标记,就能呈现为网页、移动应用、电子邮件或 API 响应。
插件的安全性具体是如何保障的?插件运行在隔离的 Cloudflare Worker 沙箱中,并附带声明式的能力清单——例如,一个只申请 read:content 和 email:send 权限的插件,实际上无法执行这两项之外的任何操作。
包含哪些入门模板?EmDash 自带博客、营销和作品集三种模板,开箱即用,涵盖 RSS 订阅源、搜索、价格卡片、常见问题以及项目/案例研究网格等功能。
像 Claude 这样的 AI 智能体能管理我的 EmDash 网站吗?可以。它附带用于编写脚本以处理内容和架构变更的 CLI、内置的 MCP 服务器,以及智能体技能文件,让 AI 工具能够构建插件或主题,或直接管理内容。
Creator
emdash-cms
Size
276 MB
Stars
13.8K
Age
6mo
Commits · 90 Days