emdash vs StoryPress — strategic audit
Cloudflare shipped the closest thing to us. What it means, and the path forward.
“emdash gives an agent a codebase. StoryPress gives an agent a design system — and gives the human the keys.”
emdash validates every architectural bet we made — structured content, agent-first, Cloudflare Workers, Dynamic Worker sandboxing — and deliberately stops exactly where our product begins.
What emdash actually is
Cloudflare's open-source "agent-portable WordPress reimplementation on Astro" — announced 2026-04-01, led by Matt Kane (Astro core, now Senior Principal Engineer at Cloudflare). MIT, beta preview, extremely active.
The content admin is genuinely good: a visual schema builder that runs real DDL, Portable Text everywhere, MCP + CLI + agent skills, passkey-first auth, and sandboxed plugins on Dynamic Worker Loaders — the same primitive as our execute_code.
The site IS a codebase the owner deploys. create-emdash ends at npm run dev.
Zero in-admin design surface. Settings are title, tagline, logo, social, SEO.
No hosted tier, no multi-site: ten client sites means ten deployments and ten D1 databases.
Going live needs a terminal — Node ≥22.12, wrangler, a hand-edited wrangler.jsonc.
No code, no terminal — what each side can actually do
Their non-dev story is real, but it is content-only. Presentation and existence are developer-or-agent-only. We are the mirror image.
| Capability — no code, no terminal | emdash | StoryPress |
|---|---|---|
| Edit content, media, menus, publish | ✓ | ✓ |
| Create new content types and fields | ✓ | ✗ |
| Change colors, fonts, spacing, radius, tone | ✗ | ✓ |
| Get the site live | ✗ | Hosted* |
| Run 10 client sites | ✗ | ✓ |
| Agent co-editing with live human preview | ✗ | ✓ |
The quadrant that is still nearly empty
A non-dev owns the site end-to-end AND an agent operates it continuously. Nothing in the researched 2026 field occupies that square. That is ours to lose.
Generation-time AI. The agent hands over at deployment.
Nearly empty. Cowork is the largest-surface contender, currently bolted onto legacy architecture.
They emit a codebase and stop.
Excellent continuous agent surface. The owner must be a developer.
Four things emdash cannot copy without becoming a different product
Presentation without code
The theme story and token system — 39 fields, OKLCH-derived hovers, a Google Fonts picker, four padding domains, per-page overrides. One codebase wears many brands with a non-dev at the wheel. emdash has literally nothing here, by design.
Hosted multi-site operation
Account-per-site, managed workers, KV, Turnstile, TLS, delivery tokens, DNS onboarding, Cloudflare analytics in-product. emdash's model cannot offer this unless Cloudflare itself builds a hosted tier.
The live-session MCP
Surgical edits landing in the human's open editor over WebSocket, navigate_to_component steering their attention, screenshots with a mandated design-critique loop. Theirs is a very good headless API; ours is a second head on a live human session. Nothing in the researched field has this.
Design quality as a measured concern
Design guide as a tool and a mandate, recipes and presets, sharp edges in the prompt — and an A/B framework honest enough to report the guide losing to design-then-port (44 vs 39 vs 27 baseline), then iterate. emdash outsources all of this to whatever agent the owner brings.
The honest risks
Our two open ends are exactly where a Cloudflare-scale player could eventually squeeze. Neither is an emergency; both are unflattering.
The honest asymmetry: emdash can do agent DDL because rendering is the owner's code — a new collection has no public page until a dev writes one. Our shared renderer is exactly why we cannot do per-site schema naively. emdash is a data point for the fork decision, not an answer to it.
Site creation is still Guy-run scripts. "Hosted" is the moat's load-bearing wall, and today it is a locally-run shell script.
The component medium is fixed. 37 renderable components; expanding them is a code-and-deploy act — while emdash lets a non-dev extend the schema instantly.
The real existential risks are distribution and per-site manual capacity. Both are entirely unchanged by emdash's existence.
Hold on Portable Text. Steal from their MCP.
Portable Text — don't migrate now
Only 3 richtext fields exist in components.json, and adoption is gated behind the Storyblok decommission anyway. Fix the format-independent problems immediately:
Write-seam richtext validation (no write path validates it at all today).
Renderer crash-proofing — a plain string SSR-crashes the renderer.
An honest agent contract, and reconcile the two contradictory prompts.
Markdown-accepting writes at the MCP boundary.
Adopt PT at the decommission seam, where the renderer must be rewritten regardless — roughly 2–3 focused weeks there, versus meaningfully more standalone now.
MCP — ours wins where our product needs it
For an agent composing good-looking pages with a human watching, ours is clearly ahead. For plain CMS administration, theirs is broader and safer per write. What to steal:
_rev optimistic concurrency — we are last-write-wins and have a documented agent-vs-human race.
Asset upload and delete tools; we cannot upload an asset or delete anything.
Their SSRF hardening details — per-hop host re-validation, credential stripping, IPv4-mapped-IPv6 normalization.
Markdown richtext writes, and query-count snapshot CI.
Recommendation: keep going
"Adopt emdash" fails technically — their content model cannot represent our composable blok tree except as an opaque blob — and it solves none of our real risks. Four moves, in order:
Promote P1 deploy-as-a-service to THE strategic priority
Not because hosting is a moat in itself, but because un-self-serviceable provisioning caps distribution at zero leverage. This is the audit's strongest internal conclusion.
Decide the components-vs-interpreter fork soon, with emdash as evidence
Schema-as-data is the sharper critique and the one place emdash genuinely raises the bar on us. Bring it to the fork decision — not into the backlog.
Take the cheap steals
_rev optimistic concurrency, richtext crash-proofing, markdown-accepting writes, their SSRF hardening details. None of it is strategic; all of it makes the product better.
Keep the escape hatch
The DeliveryProvider seam keeps the backend swappable. We bet neither on nor against a project this young — our differentiators live above that layer.
We revisit kill-or-pivot only if
- Cloudflare ships hosted emdash with an in-admin design surface and multi-site
- P1 deploy-as-a-service isn't real by end of year
- The relaunch shows the segment won't pay
Absent those, emdash is validation wearing a scary mask.
Full evidence, with path:line citations: EMDASH-COMPARISON-2026-08-11.md at the repo root, and the eight per-dimension reports in docs/research/emdash-2026-08-11/.