{"id":47731311,"url":"https://github.com/emdash-cms/emdash","last_synced_at":"2026-04-04T23:00:35.428Z","repository":{"id":348497558,"uuid":"1198246700","full_name":"emdash-cms/emdash","owner":"emdash-cms","description":"EmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress","archived":false,"fork":false,"pushed_at":"2026-04-03T22:08:22.000Z","size":9889,"stargazers_count":5979,"open_issues_count":114,"forks_count":399,"subscribers_count":49,"default_branch":"main","last_synced_at":"2026-04-03T22:09:55.883Z","etag":null,"topics":["astro","cms","emdash","typescript"],"latest_commit_sha":null,"homepage":"https://emdashcms.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emdash-cms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-01T08:45:02.000Z","updated_at":"2026-04-03T22:08:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"76df9c9b-73f0-429c-99a3-5bc6f0a6df6b","html_url":"https://github.com/emdash-cms/emdash","commit_stats":null,"previous_names":["emdash-cms/emdash"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/emdash-cms/emdash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emdash-cms%2Femdash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emdash-cms%2Femdash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emdash-cms%2Femdash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emdash-cms%2Femdash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emdash-cms","download_url":"https://codeload.github.com/emdash-cms/emdash/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emdash-cms%2Femdash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31418286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astro","cms","emdash","typescript"],"created_at":"2026-04-02T21:34:59.162Z","updated_at":"2026-04-04T23:00:35.390Z","avatar_url":"https://github.com/emdash-cms.png","language":"TypeScript","readme":"# EmDash\n\nA full-stack TypeScript CMS built on [Astro](https://astro.build/) and [Cloudflare](https://www.cloudflare.com/). 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.\n\n## Get Started\n\n\u003e [!IMPORTANT]\n\u003e EmDash depends on Dynamic Workers to run secure sandboxed plugins. Dynamic Workers are currently only available on paid accounts. [Upgrade your account](https://www.cloudflare.com/plans/developer-platform/) (starting at $5/mo) or comment out the `worker_loaders` block of your `wrangler.jsonc` configuration file to disable plugins.\n\n```bash\nnpm create emdash@latest\n```\n\nOr deploy directly to your Cloudflare account:\n\n[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/emdash-cms/templates/tree/main/blog-cloudflare)\n\nEmDash runs on Cloudflare (D1 + R2 + Workers) or any Node.js server with SQLite. No PHP, no separate hosting tier -- just deploy your Astro site.\n\n## Templates\n\nEmDash ships with three starter templates:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### Blog\n\nA classic blog with sidebar widgets, search, and RSS.\n\n- Categories \u0026 tags\n- Full-text search\n- RSS feed\n- Comment-ready\n- Dark/light mode\n\n\u003ca href=\"assets/templates/blog/latest/\"\u003e\u003cimg src=\"assets/templates/blog/latest/homepage-light-desktop.jpg\" alt=\"Blog template\" width=\"100%\"\u003e\u003c/a\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### Marketing\n\nA conversion-focused landing page with pricing and contact form.\n\n- Hero with CTAs\n- Feature grid\n- Pricing cards\n- FAQ accordion\n- Contact form\n\n\u003ca href=\"assets/templates/marketing/latest/\"\u003e\u003cimg src=\"assets/templates/marketing/latest/homepage-light-desktop.jpg\" alt=\"Marketing template\" width=\"100%\"\u003e\u003c/a\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### Portfolio\n\nA visual portfolio for showcasing creative work.\n\n- Project grid\n- Tag filtering\n- Case study pages\n- RSS feed\n- Dark/light mode\n\n\u003ca href=\"assets/templates/portfolio/latest/\"\u003e\u003cimg src=\"assets/templates/portfolio/latest/work-light-desktop.jpg\" alt=\"Portfolio template\" width=\"100%\"\u003e\u003c/a\u003e\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Why EmDash?\n\n**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](https://patchstack.com/whitepaper/state-of-wordpress-security-in-2024/). EmDash is what WordPress would look like if you started from scratch with today's tools.\n\n**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](https://developers.cloudflare.com/workers/runtime-apis/bindings/worker-loader/) 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.\n\n```typescript\nexport default () =\u003e\n\tdefinePlugin({\n\t\tid: \"notify-on-publish\",\n\t\tcapabilities: [\"read:content\", \"email:send\"],\n\t\thooks: {\n\t\t\t\"content:afterSave\": async (event, ctx) =\u003e {\n\t\t\t\tif (event.content.status !== \"published\") return;\n\t\t\t\tawait ctx.email.send({\n\t\t\t\t\tto: \"editors@example.com\",\n\t\t\t\t\tsubject: `New post: ${event.content.title}`,\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t});\n```\n\n**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](https://www.portabletext.org/), 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.\n\n**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](https://modelcontextprotocol.io/) so AI tools like Claude and ChatGPT can interact with your site directly.\n\n**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.\n\n## How It Works\n\nEmDash 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.\n\n```typescript\n// astro.config.mjs\nimport emdash from \"emdash/astro\";\nimport { d1 } from \"emdash/db\";\n\nexport default defineConfig({\n\tintegrations: [emdash({ database: d1() })],\n});\n```\n\nContent 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:\n\n```bash\nnpx emdash types\n```\n\nQuery content using Astro's Live Collections -- no rebuilds, no separate API:\n\n```astro\n---\nimport { getEmDashCollection } from \"emdash\";\nconst { entries: posts } = await getEmDashCollection(\"posts\");\n---\n\n{posts.map((post) =\u003e \u003carticle\u003e{post.data.title}\u003c/article\u003e)}\n```\n\n## Features\n\n**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.\n\n**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.\n\n**Auth** -- Passkey-first (WebAuthn) with OAuth and magic link fallbacks. Role-based access control: Administrator, Editor, Author, Contributor.\n\n**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.\n\n**Agents** -- Skill files for AI-assisted plugin and theme development. CLI for programmatic site management. Built-in MCP server for direct AI tool integration.\n\n**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.\n\n## Portable Platforms\n\n| Layer    | Cloudflare                  | Also works with                                     |\n| -------- | --------------------------- | --------------------------------------------------- |\n| Database | D1                          | SQLite, Turso/libSQL, PostgreSQL                    |\n| Storage  | R2                          | AWS S3, any S3-compatible service, local filesystem |\n| Sessions | KV                          | Redis, file-based                                   |\n| Plugins  | Worker isolates (sandboxed) | In-process (safe mode)                              |\n\n## Status\n\nEmDash is in **beta preview**. We welcome contributions, feedback, plugins, themes, and ideas.\n\n```bash\nnpm create emdash@latest\n```\n\nSee the [documentation](https://github.com/emdash-cms/emdash/tree/main/docs) for guides, API reference, and plugin development.\n\n## Development\n\nThis is a pnpm monorepo. To contribute:\n\n```bash\ngit clone https://github.com/emdash-cms/emdash.git \u0026\u0026 cd emdash\npnpm install\npnpm build\n```\n\nRun the demo (Node.js + SQLite, no Cloudflare account needed):\n\n```bash\npnpm --filter emdash-demo seed\npnpm --filter emdash-demo dev\n```\n\nOpen the admin at [http://localhost:4321/\\_emdash/admin](http://localhost:4321/_emdash/admin).\n\n```bash\npnpm test          # run all tests\npnpm typecheck     # type check\npnpm lint:quick    # fast lint (\u003c 1s)\npnpm format        # format with oxfmt\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full contributor guide.\n\n## Repository Structure\n\n```\npackages/\n  core/           Astro integration, APIs, admin UI, CLI\n  auth/           Authentication library\n  blocks/         Portable Text block definitions\n  cloudflare/     Cloudflare adapter (D1, R2, Worker Loader)\n  plugins/        First-party plugins (forms, embeds, SEO, audit-log, etc.)\n  create-emdash/  npm create emdash scaffolding\n  gutenberg-to-portable-text/  WordPress block converter\n\ntemplates/        Starter templates (blog, marketing, portfolio, starter, blank)\ndemos/            Development and example sites\ndocs/             Documentation site (Starlight)\n```\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femdash-cms%2Femdash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femdash-cms%2Femdash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femdash-cms%2Femdash/lists"}