Skip to content
On this pageTypeScript end-to-end
  1. TypeScript end-to-end
  2. Astro as the frontend
  3. Content API design
  4. Schema-as-code with seed files
  5. Plugin development: sandboxed by design
  6. MCP server: AI-native content management
  7. Local development
  8. What's missing for developers
  9. Frequently asked questions
  10. The developer opportunity

EmDash for Developers: Why This CMS Is Different

Written by Ben 6 min read Updated last month

Most CMS platforms treat developers as an afterthought. The admin panel is the product, and developers get a theme API bolted on the side. EmDash flips this. The developer experience is the core of the platform, and the admin panel is built on top of the same APIs you use.

I've been building dashtro.com on EmDash since launch week. Here's what the developer experience is actually like — what's excellent, what's different, and where the v0.1 rough edges are.

TypeScript end-to-end

EmDash is TypeScript from database queries to page templates. When you define a collection in seed.json, EmDash generates TypeScript types automatically. Your content queries return typed objects. Your IDE knows that article.data.title is a string and article.data.featured_image is an image object with id, src, alt, width, and height properties.

This catches errors before they reach production. Misspell a field name? TypeScript catches it. Forget that image fields are objects, not strings? The compiler tells you. After years of WordPress's loosely typed PHP, this feels like a different world.

Astro as the frontend

EmDash uses Astro for page rendering. If you know Astro, you already know how to build EmDash templates. Pages are .astro files with frontmatter for data fetching and HTML/JSX for rendering. Components are standard Astro components. Styling is whatever you prefer — Tailwind, vanilla CSS, CSS modules.

Astro's zero-JavaScript-by-default philosophy means your pages are fast without trying. Interactive components use Astro's island architecture — React, Vue, Svelte, or any framework you want, loaded only where needed. EmDash itself uses React for the admin panel and LiveSearch, but your site templates can use anything.

Content API design

The content API is clean and predictable. Two main functions handle most use cases:

  • getEmDashCollection("learn", { orderBy, limit, where, cursor }) — fetch multiple entries with filtering, sorting, and keyset pagination
  • getEmDashEntry("learn", slug) — fetch a single entry by slug
src/pages/index.astro
const { entries, cacheHint } = await getEmDashCollection("learn", {
  orderBy: { published_at: "desc" },
  limit: 10,
});

Both return a cacheHint that you pass to Astro.cache.set() for automatic cache invalidation when editors publish changes. This is the kind of design detail that shows the framework was built by people who ship production sites.

There's also getSeoMeta for SEO tag generation, getMenu for navigation, getTaxonomyTerms and getEntryTerms for taxonomies, and search() for full-text search. Everything returns typed results.

FunctionPurposeReturns
getEmDashCollectionFetch multiple entries with filtering and pagination{ entries, nextCursor, cacheHint }
getEmDashEntryFetch a single entry by slug{ entry, cacheHint }
getSeoMetaGenerate SEO meta tags for a page{ title, description, canonical, og }
getMenuFetch navigation menu by nameMenu with nested items
getEntryTermsFetch taxonomy terms for a content entry{ terms } keyed by taxonomy name
searchFull-text search across indexed collections{ results, cacheHint }

Schema-as-code with seed files

Your content model lives in seed.json — a JSON file that defines collections, fields, taxonomies, menus, widget areas, and sample content. EmDash reads this on first start and creates everything automatically. No migration files, no database GUIs, no clicking through admin forms to create fields.

This means your content model is version-controlled, diffable, and reproducible. Spin up a new environment with npx emdash dev and you have an identical schema with sample content. Compare that to WordPress where the content model lives in the database and you need wp-cli exports or migration plugins to replicate it.

Plugin development: sandboxed by design

EmDash plugins run in sandboxed Worker isolates. Each plugin declares capabilities in a manifest — what APIs it needs, what data it can access, what events it listens to. The runtime enforces these declarations. A plugin that requests "read content" cannot access user data or media storage.

Plugins can add custom Portable Text block types, admin pages, API routes, hooks that fire on content lifecycle events, and key-value storage. The definePlugin() API is straightforward — you export a function that returns your plugin configuration.

The ecosystem is empty right now, which means there's enormous opportunity for developers who build useful plugins early. Every EmDash site that needs analytics, contact forms, or newsletter integration represents a potential user for your plugin.

MCP server: AI-native content management

EmDash ships with a built-in MCP (Model Context Protocol) server. This exposes 33 tools for content management — creating, reading, updating, and deleting content, managing schema, searching, handling taxonomies, and working with media.

EmDash is the first CMS with a built-in MCP server. Connect an AI assistant and it can create content, manage schema, and search your site.

Connect Claude, Cursor, or any MCP-compatible AI tool to your EmDash instance, and the AI can manage your content directly. I use this daily for dashtro.com — creating articles, managing taxonomies, and querying content through natural language instead of clicking through admin forms.

This is a genuinely new capability. No other CMS has this level of AI integration built into the core. WordPress has REST APIs that AI tools can use, but MCP provides structured tool definitions that AI assistants understand natively.

Local development

The local dev experience is seamless. npx emdash dev starts Astro's dev server with Miniflare simulating D1 and R2 locally. Your database is a SQLite file on disk. No Docker, no cloud services, no environment variables to configure. The same code runs locally and in production.

Hot reload works as expected. Edit a template, see the change instantly. Edit seed.json and restart to apply schema changes. TypeScript types regenerate automatically when collections change.

What's missing for developers

Documentation is the biggest gap. The APIs are well-designed and the source code is readable, but reference docs are thin. You'll find yourself reading the EmDash source and starter templates more than documentation pages.

Testing utilities don't exist yet. There's no test harness for plugins, no mock content API for unit tests. You test against the real dev server.

The visual editing overlay has a React 19 compatibility bug. The click-to-edit experience on the frontend doesn't work currently, though the admin panel editor works fine.

Frequently asked questions

Frequently asked questions

Do I need to learn Astro to use EmDash?

You'll want to. EmDash page templates are Astro components — there's no way around it. But Astro is a very small surface area compared to Next.js or Nuxt. If you know HTML and TypeScript, you can learn Astro in an afternoon.

Can I write plugins in JavaScript instead of TypeScript?

Technically yes — TypeScript compiles to JavaScript. But the whole point of EmDash's type system is catching mistakes at compile time. Writing plugins in plain JS gives up the main DX advantage.

How do I test EmDash plugins?

There's no test harness yet. You test against the real dev server. This is one of the real rough edges at v0.1 — plugin authors who ship confidently need their own test infrastructure for now.

Is MCP useful if I'm not using AI for content?

Marginally. MCP's value is the AI workflow. If you're editing everything by hand, the admin panel and CLI are more efficient. MCP earns its place when you have an AI assistant drafting or querying content.

The developer opportunity

EmDash's developer experience is already strong in the areas that matter — typed queries, modern tooling, clean APIs, and sandboxed extensibility. The rough edges are real but fixable. What matters is the architectural foundation, and that's solid.

For developers who want to build in the EmDash ecosystem, the timing is ideal. No plugins exist. No premium themes exist. No services exist. Every developer need in the EmDash ecosystem is an unmet need. The first quality plugin for analytics, contact forms, or SEO auditing will own that category for years.

Build your first plugin →