{"id":98101,"date":"2026-10-14T00:38:00","date_gmt":"2026-10-14T04:38:00","guid":{"rendered":"https:\/\/overcentral.com\/en\/?p=98101"},"modified":"2026-09-29T08:06:29","modified_gmt":"2026-09-29T12:06:29","slug":"emdash-starter-templates-comparison-98101","status":"publish","type":"post","link":"https:\/\/overcentral.com\/en\/emdash-starter-templates-comparison-98101\/","title":{"rendered":"EmDash Starter Templates: Which One Actually Fits Your Workflow?"},"content":{"rendered":"<p>You&#8217;ve run the <code>npm create emdash@latest<\/code>codecodecodecode command. You&#8217;ve seen the wizard. Blog, portfolio, marketing site. Three options, presented like a choose-your-own-adventure for developers who already know what they&#8217;re doing.<\/p>\n<p>But here&#8217;s what the documentation doesn&#8217;t tell you. The template you pick at install time isn&#8217;t just a skin swap. It changes the content model, the default plugins, the theme architecture, and \u2014 critically \u2014 the migration path if you&#8217;re coming from WordPress.<\/p>\n<p>Let&#8217;s skip the obvious. No &#8220;blog is for writers, portfolio is for creatives&#8221; hand-waving. Instead, here&#8217;s what each template actually commits you to, architecturally speaking.<\/p>\n<h2>The Blog Template: Content Collections First<\/h2>\n<p><a href=\"https:\/\/overcentral.com\/en\/eu-cra-reporting-requirements-80362\/\" title=\"EU CRA Demands What Shipped and When You Knew\" data-iacss-internal=\"1\">When you<\/a> select blog, <a href=\"https:\/\/emdash.dev\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">EmDash<\/a> configures its content schema around two post types: <code>posts<\/code>codecodecodecode and <code>pages<\/code>codecodecodecode. That&#8217;s it. No custom content types out of the box. The template ships with a single-column layout, a sidebar widget area for the primary navigation, and SEO metadata fields pre-attached to every post.<\/p>\n<p>What matters for the experienced developer: the blog template uses Astro&#8217;s content collections under the hood. Your posts live as structured JSON (portable text, not HTML). This means you can query them via the built-in API without parsing markup \u2014 something <a href=\"https:\/\/overcentral.com\/en\/rogue-ai-agents-liability-vacuum-97898\/\" title=\"Rogue AI agents expose liability vacuum as OpenAI faces claims\" data-iacss-internal=\"1\">AI agents<\/a> and headless consumers handle natively.<\/p>\n<p>The blog template also enables comments with AI moderation by default. If you&#8217;re migrating a high-traffic WordPress blog, check whether the moderation rules match your existing workflow. They don&#8217;t. You&#8217;ll need to configure those manually.<\/p>\n<h2>The Portfolio Template: Projects as First-Class Citizens<\/h2>\n<p>The portfolio template introduces a third content type: <code>projects<\/code>codecodecodecode. Each project has client name, year, a link field, and a rich text body. The default theme renders these as a grid with filtering by category or tag.<\/p>\n<p>Here&#8217;s the non-obvious part. The portfolio template ships with a contact form plugin pre-installed. That plugin is a sandboxed dynamic worker \u2014 it requests <code>read content<\/code>codecodecodecode and <code>send email<\/code>codecodecodecode capabilities in its manifest. It cannot touch your database or your media library. If you&#8217;re used to form plugins that store submissions as custom post types in WordPress, you&#8217;ll need to rethink that pattern. In EmDash, form submissions are not content types. They&#8217;re ephemeral data handled by the plugin&#8217;s sandbox.<\/p>\n<p>The portfolio template also enables <code>bylines<\/code>codecodecodecode \u2014 a content metadata field for attributing work to specific authors or contributors. This is not a taxonomy. It&#8217;s a separate entity type. If your workflow requires complex author management (multiple roles, guest contributors, etc.), you&#8217;ll want to test this early.<\/p>\n<h2>The Marketing Site Template: Conversion-Ready Architecture<\/h2>\n<p>The marketing site template is the most opinionated of the three. It includes a <code>sections<\/code>codecodecodecode system \u2014 reusable blocks (header, about, sign-up, etc.) that you can compose into pages. Think of it as a lightweight theme builder, not a page builder. You don&#8217;t drag and drop. You select a section, configure its fields, and the Astro frontend renders it.<\/p>\n<p>This template also ships with redirect management built-in. That&#8217;s a direct response to one of WordPress&#8217;s pain points \u2014 needing a plugin for 404 handling and redirects. In EmDash, it&#8217;s a core feature on the marketing template.<\/p>\n<p>The marketing template uses the most Cloudflare-specific infrastructure. It assumes D1 for the database, R2 for media storage, and Workers for compute. Self-hosting this template on a plain Node.js server works, but you lose the edge caching and the sandboxed plugin execution. For a marketing site where uptime and speed matter, that tradeoff is worth thinking about.<\/p>\n<h2>What the Wizard Doesn&#8217;t Tell You<\/h2>\n<p>All three templates share a common base: the same admin UI, the same user role system (administrator, editor, author, contributor), the same passkey authentication, and the same built-in SEO fields. They also all support dark mode out of the box \u2014 but the default themes are minimal. You&#8217;re expected to customize them with Tailwind, TypeScript, and Astro components.<\/p>\n<p>The real differentiator is the content model and the default plugins. If you pick the blog template and later realize you need a projects content type, you can add it via the admin panel. But that content type is stored in the database, not in code. If you&#8217;re doing infrastructure-as-code deploys, that&#8217;s a problem. The marketing template avoids this by using sections \u2014 but sections are also database-defined.<\/p>\n<h2>The Migration Angle<\/h2>\n<p>If you&#8217;re migrating from WordPress, the template <a href=\"https:\/\/overcentral.com\/en\/ichra-choice-arrangements-label-97925\/\" title=\"ICHRA Gets CHOICE Arrangements Label from CMS, SBA\" data-iacss-internal=\"1\">choice<\/a> affects the import. The blog template maps WordPress posts and pages cleanly. The portfolio template maps custom post types \u2014 but only if your WordPress export includes them. The marketing template imports content into sections, which is a structural conversion. Expect to spend time re-mapping fields.<\/p>\n<p>Based on early reports from developers who tested the beta, the WordPress import handles Yoast SEO fields (title, description, image) and maps them to EmDash&#8217;s built-in SEO metadata. But anything in ACF, Jet Engine, or custom meta fields \u2014 that&#8217;s a manual job regardless of template.<\/p>\n<h2>The Verdict for Practitioners<\/h2>\n<p>Pick the blog template if you&#8217;re building a content-driven site with predictable structure and want the cleanest migration path from WordPress. Pick the portfolio template if you need projects as a distinct content type and want a contact form that&#8217;s sandboxed by default. Pick the marketing template if you&#8217;re building a conversion-focused site with reusable sections and need redirect management out of the box.<\/p>\n<p>But know this: the template you choose is reversible. You can add content types, change themes, and install plugins later. The choice at install time is about time-to-first-deployment, not lifetime commitment.<\/p>\n<p>Based on what most production-ready sites actually need \u2014 an e-commerce migration, a membership system, or complex form handling \u2014 none of the three templates are sufficient alone. They&#8217;re starting points. The real work begins after the wizard ends.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#8217;ve run the npm create emdash@latestcodecodecodecode command. You&#8217;ve seen the wizard. Blog, portfolio, marketing site. Three options, presented like a choose-your-own-adventure for developers who already know what they&#8217;re doing. But here&#8217;s what the documentation doesn&#8217;t tell you. The template you pick at install time isn&#8217;t just a skin swap. It changes the content model, the [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":100468,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98101.png","fifu_image_alt":"EmDash Starter Templates: Which One Actually Fits Your Workflow?","footnotes":""},"categories":[31],"tags":[],"class_list":["post-98101","post","type-post","status-publish","format-standard","has-post-thumbnail","category-technology"],"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/98101.png","fifu_image_alt":"EmDash Starter Templates: Which One Actually Fits Your Workflow?","_links":{"self":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/comments?post=98101"}],"version-history":[{"count":1,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98101\/revisions"}],"predecessor-version":[{"id":100469,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/98101\/revisions\/100469"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media\/100468"}],"wp:attachment":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media?parent=98101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/categories?post=98101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/tags?post=98101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}