Web Design

Picking a headless CMS for a Jamstack rebuild

DSN

A client asked us to rebuild their marketing site as a Jamstack app this year, which meant picking a headless CMS from scratch rather than defaulting to WordPress the way most of our previous rebuilds have. We shortlisted three options and ran a genuine two-week evaluation with the client's actual content team involved from day one, rather than making the call on developer preference alone.

What we actually evaluated

We scored each option against five criteria that mattered for this specific client: editor experience for non-technical staff, developer API ergonomics, pricing at their expected content volume, preview mode quality for content not yet published, and localization support, since the client operates in three languages. Each shortlisted CMS got the same test: the client's marketing team spent real time in each one building a mock landing page and a blog post, while our developers built out the same page template against each API to compare integration effort directly rather than relying on marketing copy from the CMS vendors themselves.

  • Editor experience for non-technical staff, tested by having the client's actual marketing team build a mock page in each tool without developer help.
  • Developer API ergonomics, including how naturally the content model mapped to TypeScript types and how good the documentation was for less common query patterns.
  • Pricing at the client's expected content volume and traffic, projected a year out rather than at launch-day numbers.
  • Preview mode quality for unpublished content, since the client's editorial workflow depends heavily on stakeholder review before anything goes live.
  • Localization support across the three languages the client publishes in.

The tradeoff that decided it

The flashiest option had the best developer experience by a clear margin: a clean GraphQL API, generous free tier, and genuinely pleasant documentation. But it had the worst editor experience of the three, with a content modeling interface clearly built with developers in mind first, and the client's marketing team is who has to log in and use it every single day, not us. Watching a marketing coordinator get visibly frustrated trying to find a simple text field buried three tabs deep during the evaluation was the moment that settled the decision internally, even before we tallied the formal scores.

We ultimately picked the option with the plainest interface, one that a developer might call boring, because it required the least training for non-technical editors and mapped its content structure onto concepts, pages, sections, and blocks, that the client's team already understood from years of using a page-builder plugin on their old WordPress site. It had fewer bells and whistles for developers: a REST API rather than GraphQL, and a less elegant TypeScript integration story that took us an extra day of custom type generation to get comfortable with. That tradeoff was worth making.

Rollout and what we'd watch for next time

Once the decision was made, migrating the client's existing content took about a week, mostly scripted against the old CMS's export format, with a manual pass afterward to fix a handful of rich-text fields that didn't map cleanly between the two systems' block models. Webhook-triggered rebuilds on content publish, tied into our static site host's deploy hooks, meant editors saw their changes go live within about two minutes of hitting publish, which was a hard requirement the client had called out early and one that ruled out at least one CMS we'd otherwise considered.

The three candidates, without naming names

It's worth describing what actually distinguished the three shortlisted options beyond the headline tradeoff, since the differences ran deeper than just developer-friendly versus editor-friendly. The first, the flashiest option mentioned above, modeled content as arbitrary structured schemas defined through code-first configuration, which gave developers enormous flexibility but meant every new content type required a developer to touch a schema file before an editor could use it. The second, a mid-tier option, split the difference reasonably well, with an editor-manageable schema builder and a REST API that was serviceable if unremarkable, but its pricing model charged per API request in a way that made the client's projected traffic a year out meaningfully more expensive than either of the other two. The third, the one we ultimately chose, sacrificed some developer flexibility, no schema-as-code option, for an editor experience the client's team picked up in under an hour, and predictable flat-tier pricing that didn't punish traffic growth.

Vendor lock-in and the exit plan we insisted on

Every headless CMS decision carries a lock-in risk that's easy to underweight during an evaluation focused on launch-day usability, so we made content portability part of the decision from the start rather than an afterthought. All three finalists offered a content export in a reasonably open format, but only two made it possible to export the content model itself, not just the content, in a form that could realistically be reconstructed elsewhere; we treated that as close to a hard requirement given how much client CMS churn we've seen over multi-year engagements. We also negotiated with the client to keep the site's build pipeline decoupled from the CMS choice, meaning the static site generator reads from a normalized content shape produced by an adapter layer rather than calling the CMS's API directly from every page template, so a future CMS migration, if it ever comes to that, wouldn't require touching every page template at once.

Localization turned out to matter more than we initially scored it

We weighted localization as one of five roughly equal criteria going in, but it ended up mattering more in practice than the initial scoring suggested, since it interacted badly with the editor-experience question for two of the three candidates. The flashiest, developer-first option handled localized content as a configuration layered on top of its schema-first content model, which was technically flexible but meant a non-technical editor adding a French translation of a page had to understand a locale-key structure that wasn't visually distinct from the English version, and predictably led to editors accidentally editing the wrong locale's content during the pilot. The option we chose modeled each locale as a visibly separate, clearly labeled version of a page inside the same editing interface, side by side, which the client's editors found intuitive almost immediately and which meaningfully increased its score relative to how we'd initially weighted it before actually watching editors work with translated content hands-on.

Image handling turned out to be its own evaluation criterion

None of our original five criteria explicitly covered image and media handling, which turned out to be an oversight once the evaluation was underway. All three candidates offered some form of built-in image optimization and a CDN-backed asset pipeline, but they differed meaningfully in how much control an editor had over cropping and focal points without developer involvement. The client's marketing team routinely needs to swap a hero image and have it look right across a hero banner, a card thumbnail, and a social share preview simultaneously, and only one of the three candidates let an editor set a focal point once and have it applied sensibly across every rendered size. We added image handling as an informal sixth criterion partway through the evaluation once this became clear, and it reinforced rather than changed the eventual decision.

Training the client's team after launch

Picking the editor-friendly option didn't mean training was unnecessary, just shorter than it would have been otherwise. We ran a half-day session with the client's full content team covering the new content model's structure, the difference between a draft and a published version, and how the preview link worked in practice, followed by office hours for the first two weeks after launch to catch questions that only surface once people are using the system for real content rather than a training exercise. Attendance and question volume during those office hours dropped off noticeably after the first week, which we took as a good sign that the interface really was as intuitive as the evaluation had suggested rather than editors quietly struggling in silence.

The cost overrun risk we flagged before signing

Because pricing was scored against traffic projected a year out rather than launch-day numbers, we made a point of documenting the assumptions behind that projection explicitly in our recommendation to the client, rather than presenting a single confident number. If the client's traffic grew meaningfully faster than projected, most plausible for the mid-tier, per-request-priced option we ultimately ruled out partly on cost grounds, the pricing conclusion could flip within a year or two. Flagging that risk upfront meant the client's finance team went in with realistic expectations rather than being surprised by a renewal quote that didn't match what they remembered agreeing to, and it's a step we now build into every CMS recommendation regardless of which option looks cheapest on paper at evaluation time.

Preview mode, and why it nearly changed our decision

Preview mode, letting a stakeholder view unpublished content exactly as it will appear live before approving it, was the criterion that came closest to flipping the decision. The mid-tier option's preview implementation was, on paper, the most technically elegant of the three, generating a live preview URL through a webhook straight into our staging environment. But it required a developer to have already wired up preview-specific routing on the front end, an integration cost none of the other two carried, and the client's timeline didn't have room to absorb that extra setup work before launch. We ultimately treated preview mode as a tie between the remaining two candidates once that integration cost was accounted for, which meant the final decision came down more heavily on the editor-experience and localization criteria than it might have on a project with a longer runway for custom preview tooling.

Developer experience matters, and we wouldn't ignore it entirely on a future evaluation, but for content-heavy client sites, the people editing content every day should weigh more heavily in the decision than the people building the integration once and then moving on to the next project. We've since used the same weighted-criteria evaluation approach, with real end users testing the tools directly, on two other client CMS decisions this year, and it's consistently surfaced the right answer faster than debating it internally would have.

← Back to the journal

Have a project in mind?
Let’s talk.

Tell us where you are and where you want to go. We'll map the fastest route between the two.

Currently accepting new clients