Headless CMS Comparison: SonicJS vs Payload, Strapi, Directus, Sanity & Contentful
These six are among the most popular headless CMSs β but they make very different trade-offs. SonicJS runs on Cloudflare Workers with a D1 (SQLite) database. Payload, Strapi, and Directus are mature, self-hostable Node.js platforms. Sanity and Contentful are hosted SaaS content platforms with deep enterprise features but no self-hosting and significant plan-gating. The table below is a full inventory of 125+ capabilities across 13 categories β meant as an honest reference, including the many places where the others are still ahead of SonicJS.
6 products compared β scroll the table sideways to see Sanity & Contentful β
| Capability | SonicJS | Payload | Strapi | Directus | Sanity | Contentful |
|---|---|---|---|---|---|---|
| Architecture & Runtime | ||||||
| Runtime | Cloudflare Workers | Node.js | Node.js | Node.js | Hosted SaaS | Hosted SaaS |
| Deployment model | Global edge | Single-region | Single-region | Single-region | Managed SaaS | Managed SaaS |
| Edge / serverless runtime | β | PartialVercel | β | β | PartialCDN | PartialCDN |
| Database | D1 (SQLite) | Postgres Β· Mongo | Postgres Β· MySQL | Postgres Β· +5 | Content Lake | Proprietary |
| Data layer / ORM | Drizzle | Drizzle Β· Mongoose | Knex | Knex | GROQ | β |
| Typical cold start | 0β5 ms | 100β300 ms | 500β2000 ms | 300β1000 ms | n/a | n/a |
| Global edge distribution | β | β | β | β | β | β |
| Built-in caching | 3-tier | PartialManual | PartialPlugin | PartialCache | API CDN | API CDN |
| Auto-scaling | β | PartialInfra | PartialInfra | PartialInfra | β | β |
| Self-hostable anywhere | PartialCF only | β | β | β | β | β |
| Docker support | β | β | β | β | β | β |
| Official managed cloud | β | PaidPaused | Paid | Paid | β | β |
| Pricing & Licensing | ||||||
| License | MIT | MIT | MIT (+ EE) | MSCL | MIT / SaaS | Proprietary |
| Free to self-host | β | β | β | Partial<$5M rev | β | β |
| Free cloud tier | PartialCF free tier | β | β | β | β | β |
| Paid cloud entry price | Free / ~$5 | $35+/mo | $15+/mo | $25+/mo | $15/seat | ~$300/mo |
| Features behind paywall | β | β | PaidSeveral | PartialSome | PaidSeveral | PaidMany |
| Content Modeling | ||||||
| Collections / content types | β | β | β | β | β | β |
| Single types / globals | Partial | β | β | Partial | β | Partial |
| Repeatable / array fields | β | β | β | β | β | β |
| Reusable component / group fields | β | β | β | Partial | β | Partial |
| Blocks / dynamic zones | β | β | β | Partial | β | β |
| One-to-one relationships | Partial | β | β | β | β | β |
| One-to-many relationships | β | β | β | β | β | β |
| Many-to-many relationships | Partial | β | β | β | β | β |
| Polymorphic relationships | Partial | β | Partial | β | β | β |
| Conditional field logic | β | β | β | β | β | β |
| Field-level validation | β | β | β | β | β | β |
| Computed / virtual fields | β | Partial | Partial | Partial | Partial | β |
| Rich text editor | TinyMCE | Lexical | CKEditor | TinyMCE | Portable Text | Rich Text |
| Markdown field | β | Partial | β | β | Plugin | β |
| JSON field | β | β | β | β | Partial | β |
| Custom field types | Partial | β | β | Plugin | β | Plugin |
| UI / presentational fields | β | β | Partial | β | Partial | Partial |
| Field-level localization | Roadmap | β | β | β | Plugin | β |
| Built-in field types (approx.) | ~21 | ~22 | ~15 | ~25 | ~13 | ~12 |
| Content Management & Editorial | ||||||
| Draft & publish | β | β | β | β | β | β |
| Version history / revisions | β | β | Paid | β | Partial3-day free | β |
| Autosave | β | β | β | β | β | β |
| Scheduled publishing | β | β | Paid | PartialFlows | Paid | Paid |
| Live preview | β | β | Paid | β | β | Partial |
| Editorial workflow / review stages | β | Partial | Paid | Partial | Partial | Paid |
| Bulk edit / delete | β | β | β | β | Partial | β |
| Document duplication | β | β | β | β | β | β |
| Soft delete / trash | β | β | β | Partial | Partial | Partial |
| Concurrent edit locking | β | β | Partial | Partial | β | Partial |
| Editorial comments | β | β | β | β | Paid | Paid |
| Real-time collaboration | β | β | β | β | β | Partial |
| APIs & Integration | ||||||
| REST API | β | β | β | β | β | β |
| GraphQL API | Roadmap | β | Plugin | β | β | β |
| GraphQL subscriptions | β | β | β | β | β | β |
| Realtime / WebSockets | Roadmap | β | β | β | β | β |
| Local / server-side API | β | β | β | β | β | β |
| Webhooks | β | PartialHooks | β | β | β | β |
| Filtering / sorting / pagination | β | β | β | β | β | β |
| Deep relationship population | Partial | β | β | β | β | β |
| Aggregation queries | β | Partial | β | β | β | β |
| Field selection / sparse fieldsets | β | β | β | β | β | β |
| Custom endpoints | β | β | β | Plugin | Partial | Plugin |
| OpenAPI / Swagger spec | β | Plugin | β | β | β | Partial |
| Authentication & Authorization | ||||||
| End-user / app auth | β | β | β | β | β | β |
| JWT / token auth | β | β | β | β | β | β |
| API keys / tokens | β | β | β | β | β | β |
| OAuth / social login | Plugin | Partial | β | β | β | Partial |
| SSO / SAML | Roadmap | Paid | Paid | β | Paid | Paid |
| Magic link | Plugin | β | β | β | β | β |
| OTP / 2FA / MFA | PluginOTP | Plugin | β | β | Partial | β |
| Role-based access control | β | β | PartialAdv = EE | β | Partial2 free | Paid |
| Collection-level permissions | β | β | β | β | Paid | Paid |
| Field-level permissions | β | β | Paid | β | Paid | Paid |
| Document / row-level access | Partial | β | Partial | β | Paid | Paid |
| Custom access-control functions | β | β | β | Partial | Paid | β |
| Password reset | β | β | β | β | β | β |
| Media & Assets | ||||||
| Media library | β | β | β | β | β | β |
| Image resizing / transforms | β | β | β | β | β | β |
| Focal point | β | β | β | β | β | β |
| Cloud storage adapters | R2 | β | Plugin | β | β | β |
| File metadata | β | β | β | β | β | β |
| Alt text / captions | β | β | β | β | Partial | Partial |
| Folders / organization | β | β | β | β | Partial | Partial |
| Image optimization | β | Partial | β | β | β | β |
| CDN integration | β | Partial | Partial | Partial | β | β |
| Internationalization | ||||||
| Content localization (i18n) | Roadmap | β | β | β | Plugin | β |
| Locale fallbacks | Roadmap | β | β | Partial | Plugin | β |
| Admin UI translations | β | β | β | β | β | Partial |
| RTL support | β | β | Partial | β | Partial | β |
| Admin Panel & UI | ||||||
| Built-in admin UI | HTMX | React / Next | React | Vue | React (Studio) | Web app |
| Custom components / fields | Partial | β | β | Plugin | β | Plugin |
| Customizable dashboard | β | β | Partial | β | β | Plugin |
| Custom admin views / routes | β | β | β | Plugin | β | Plugin |
| Theming / white-label | Partial | β | Partial | Partial | Partial | Paid |
| Dark mode | β | β | β | β | β | β |
| List view configuration | β | β | β | β | β | β |
| Conditional field display | β | β | β | β | β | β |
| Extensibility & Automation | ||||||
| Plugin / extension system | β | β | β | β | β | β |
| Lifecycle hooks | β | β | β | β | Partial | Partial |
| Middleware | β | Partial | β | Partial | Partial | β |
| Custom endpoints | β | β | β | β | Partial | Plugin |
| Cron / scheduled jobs | Partial | β | β | β | Partial | Partial |
| Background jobs / queues | β | β | β | Partial | β | β |
| Email sending | β | β | Plugin | β | β | β |
| Visual automation builder | β | β | β | β | β | Paid |
| Custom CLI | β | Partial | Partial | Partial | β | β |
| Developer Experience | ||||||
| TypeScript support | β | β | β | β | β | β |
| Schema as code | β | β | β | β | β | β |
| Type generation from schema | Partial | β | β | Partial | β | Plugin |
| DB / content migrations | β | β | Partial | β | β | β |
| Data seeding | β | Partial | Partial | Partial | Partial | Partial |
| CLI scaffolding | β | β | β | β | β | Partial |
| Official JS / TS SDK | β | β | β | β | β | β |
| API playground / docs UI | β | Partial | β | Partial | β | β |
| Security & Operations | ||||||
| Rate limiting | β | Partial | Partial | β | β | β |
| CSRF protection | β | β | Partial | Partial | β | Partial |
| CORS config | β | β | β | β | β | β |
| Audit logs | β | Partial | Paid | β | Paid | Paid |
| Field encryption | β | Partial | β | β | β | β |
| GDPR / data-export tools | Partial | Partial | Partial | β | Partial | β |
| Bot protection (CAPTCHA) | PluginTurnstile | β | β | β | Partial | Partial |
| Database transactions | β | β | β | β | β | β |
| Multi-tenancy | Partial | Plugin | β | Partial | Partial | β |
| Ecosystem & Maturity | ||||||
| First released | 2018 | 2021 | 2015 | 2012 | 2017 | 2013 |
| GitHub stars (approx.) | ~1.6k | ~43k | ~72k | ~36k | ~6.2k | Closed |
| Official plugins / marketplace | ~25 bundled | ~10 official | Marketplace | Marketplace | Marketplace | Marketplace |
| Visual page builder | β | Partial | β | Partial | Partial | Paid |
| Built-in AI features | β | β | Paid | β | Partial | Paid |
Data last verified June 2026against each projectβs official docs, GitHub, and pricing pages. Sanity and Contentful are hosted SaaS platforms, so βself-hostableβ rows are No and several features are plan-gated. Corrections welcome via GitHub.
How to read this
The matrix isn't scored or weighted β pick the rows that matter for your project. A few things worth knowing as context:
Architecture is the real fork in the road
SonicJS compiles to Cloudflare Workers, so there's no server to keep warm β cold starts are effectively 0β5 ms and reads are served from the global edge. Payload, Strapi, and Directus run as Node.js processes you host in a single region β flexible on database choice and battle-tested, but cold starts and global latency depend on your infrastructure. Directus is database-first (it layers onto an existing SQL database). Sanity and Contentful sidestep hosting entirely: their content lives in a managed cloud delivered over a global CDN, so you never run a server β but you also can't self-host, and you're billed per seat/usage.
Feature maturity: the incumbents lead in many areas
This is the honest part. Compared to SonicJS, the older platforms ship a number of things SonicJS doesn't have yet or only partially supports β most notably GraphQL, real-time/WebSockets, internationalization, soft-delete/trash, conditional fields, an official SDK, SSO/SAML, and richer relationship modeling. Directus in particular is very deep (Flows automation, Insights dashboards, GraphQL subscriptions). Strapi and Directus also have far larger ecosystems and longer track records.
Where SonicJS is differentiated
Its edge-native runtime (sub-50ms global reads, near-zero cold starts), built-in three-tier caching, and the fact that everything ships in the open-source core with no paywalls. Note the trade-offs that come with the edge model: a single database engine (D1/SQLite) and Cloudflare-only hosting rather than run-anywhere Docker.
Pricing & feature gating
The self-hostable four are free to run (Directus requires a commercial license above $5M revenue). What's gated differs: Strapi puts version history, scheduled publishing, Live Preview, audit logs, advanced RBAC, and SSO behind paid Growth/Enterprise tiers; Payload is fully open-source (managed Cloud currently paused post-Figma-acquisition); Directus is source-available with a small-org grant; SonicJS has no feature paywalls and runs on Cloudflare's free tier. The two SaaS platforms gate more heavily: Sanity charges per seat and gates SSO, custom roles, comments, and content releases; Contentful has a usable free tier but reserves scheduled publishing, workflows, SSO, RBAC, and visual editing for plans starting around $300/mo.
Which should you pick?
Choose SonicJS ifβ¦
- You want global edge performance with near-zero cold starts
- You're already on (or moving to) Cloudflare
- You want every feature free, with no per-seat or Enterprise gating
- You value AI-agent-ready docs and a TypeScript-first codebase
Choose Payload / Strapi / Directus ifβ¦
- You need GraphQL or real-time today
- You depend on Postgres, MySQL, or MongoDB specifically
- You want a large ecosystem and the control of self-hosting
- Your traffic is regional and edge latency isn't a priority
Choose Sanity / Contentful ifβ¦
- You'd rather not run any infrastructure at all
- You need enterprise governance (audit, SSO, workflows) and have budget
- Sanity: real-time multiplayer editing and GROQ matter to you
- Contentful: you're standardizing a large org on a composable platform
Deep-dive comparisons
Want a closer look at a specific matchup? These guides go beyond the matrix with benchmarks, migration notes, and real-world developer feedback:
- SonicJS vs Strapi
- Strapi vs Payload vs SonicJS
- Directus vs Payload vs SonicJS
- Strapi vs Directus vs SonicJS
- Sanity vs Contentful vs SonicJS
- Strapi vs Contentful vs SonicJS
- Browse all CMS comparisons β
Frequently asked questions
Is SonicJS a good alternative to Strapi, Payload, or Directus?
SonicJS is a strong fit when you want an edge-native CMS on Cloudflare Workers with near-zero cold starts and no feature paywalls. The Node.js incumbents (Payload, Strapi, Directus) are more mature and still lead in areas like GraphQL, internationalization, real-time, and database flexibility β several of which are on the SonicJS roadmap. Pick based on whether edge performance or breadth of features matters more for your project.
Which headless CMS is the fastest?
Architecturally, SonicJS has the lowest cold start (0β5 ms) because it runs on Cloudflare Workers at the edge rather than a single-region Node.js server, so reads are served close to users worldwide. Payload, Strapi, and Directus performance depends on your hosting and caching setup. Real-world numbers vary by workload, so benchmark for your own use case.
Which of these headless CMSs are free and open source?
SonicJS, Payload, Strapi, and Directus are all self-hostable. SonicJS and Payload are MIT licensed. Strapi's Community edition is MIT but gates features like version history, scheduled publishing, Live Preview, audit logs, advanced RBAC, and SSO behind paid tiers. Directus uses the source-available MSCL license (free under $5M revenue). Sanity and Contentful are hosted SaaS β only Sanity's Studio editor is open source (MIT); their content backends are proprietary and can't be self-hosted, and Contentful is fully closed-source.
Does SonicJS support GraphQL and internationalization (i18n)?
Not yet β GraphQL and i18n are on the SonicJS roadmap. Today SonicJS ships a REST API with an OpenAPI spec. Payload, Strapi, and Directus all offer GraphQL and i18n today (Directus also offers GraphQL subscriptions and real-time over WebSockets).
Which headless CMS should I choose?
Choose SonicJS for global edge performance on Cloudflare with everything in the free core. Choose Payload for a Next.js-native, deeply typed developer experience. Choose Strapi for the largest plugin ecosystem and a mature admin. Choose Directus to layer a CMS and visual automation onto an existing SQL database. Choose Sanity for real-time multiplayer editing and the GROQ query language, or Contentful for an enterprise-grade composable platform you don't have to operate. The feature matrix above breaks down all six across 125+ capabilities.
Spot something out of date? Competitor pricing and features change fast. Open an issue or PR on GitHub and we'll correct it.