1.45Now runs on Cloudflare Workers, Bun and Deno

One TypeScript file. A whole backend.

Define data, access and logic in easy-cms.config.ts. You get a database, a typed API and REST, sign-in, files, jobs and an admin at /admin.

$npm create easy-cms@latest
MIT licensedNext.js · Nuxt · StandaloneAdmin in English & ไทย
localhost:3000/admin
Generated from your config.Generated from your config.
easy-cms.config.tscollection: bookings
hooks: { beforeChange: [checkSlotIsFree] },
access: { delete: ({ user }) => user?.role === 'admin' },
actions: [{ name: 'remind', run: sendReminder }],
// bookings: admin, REST, typed API and jobs from here
Runs with
  • Next.js
  • Nuxt
  • Node.js
  • Bun
  • Deno
  • Cloudflare Workers
  • Vercel
  • Docker
  • PostgreSQL
  • SQLite
  • Turso
npm downloads in total
29,241
releases since 1.0 on 17 Oct
48
tests on every pull request
1,200+
features behind a paywall
0
easycms.dev runs on Easy CMS. Read its source
Code-first

Three files and your app has a backend.

Describe collections and fields in TypeScript. The admin forms, validation, access rules and the typed API are built from that one file.

import { defineConfig } from '@easy-cms/core'
import { postgres } from '@easy-cms/db-postgres'
import { seoPlugin } from '@easy-cms/plugin-seo'

export default defineConfig({
  secret: process.env.EASY_CMS_SECRET!,
  db: postgres({ url: process.env.DATABASE_URL! }),
  localization: { locales: ['en', 'th'], defaultLocale: 'en' },
  collections: [
    {
      slug: 'posts',
      drafts: true, versions: true, schedule: true,
      useAsTitle: 'title',
      fields: [
        { name: 'title', type: 'text', required: true, localized: true },
        { name: 'slug', type: 'slug', from: 'title' },
        { name: 'body', type: 'richText', localized: true },
      ],
    },
  ],
  plugins: [seoPlugin({ collections: ['posts'] })],
})
The admin

Generated from your config. Ready for your clients.

Your clients edit and preview content, give people roles and see who changed what, with AI that writes alt text and translations, and integrations they connect themselves. In English or Thai.

your-app.com/admin
AI writes, people check
Multi-runtime

Pick where it runs.

The same config runs on a single VPS, on Vercel, at the edge on Cloudflare Workers or across many containers. Choose by the job.

easy-cms.config.tsSQLite and the disk · Node.js or Bun
db: sqlite({ url: 'file:./cms.db' }),
upload: { dir: 'uploads' },
// one process; jobs run every minute by themselves
$npx easy-cms serve --port 3000
Read the guide
Tested on every pull request
Node.jsBunDenoCloudflare WorkersSQLitePostgreSQL
plus PgBouncer and upgrades from 0.10
Compare

Others make you choose. Easy CMS doesn’t.

Team features without an enterprise plan, a schema you review in pull requests, and no second server to run. Four things developers ask for, checked against each product’s own site.

Easy CMS next to Payload, Strapi, Directus and WordPress
Our pickEasy CMSPayloadStrapiDirectusWordPress
SSO, roles and an audit log, freeWhat teams pay for first.MIT, every featureSSO is an Enterprise planSSO and audit logs are EnterpriseNo SSO in the free CoreNot confirmed
No second server to runOne deploy, one thing to secure.Inside Next.js or Nuxt, or standaloneInside Next.js onlyA separate Node serverA separate Node serverA separate PHP app
The schema is typed codeReviewed in pull requests, typed in your app.TypeScript config in your repoTypeScript config in your repoBuilt in the admin, saved as filesBuilt in the studio, YAML snapshotsPHP post types or plugins
Admin and docs in ThaiFor Thai editors and the people who pay you.Every admin string and docs pageAdmin near-completeAbout a quarter of the adminPartial, by the communityAbout two-thirds of the admin

Easy CMS: 4 of 4. No other product here gets more than one.

Checked against each product’s own site on 17 Oct 2026. The full comparison also says when another product is the better choice.

See the full comparison
AI-ready

Your AI assistant can write it.

The config is typed TypeScript and the docs ship as llms.txt, so Claude Code, Cursor or Copilot write collections, access rules and hooks that compile. Agents reach the data through MCP, under the same roles as people.

Works withClaudeCursorGitHub Copilot
You

Add a bookings collection: customer, service, start time and status. Front desk can create and change bookings; only admins delete them.

easy-cms.config.ts+ 14 lines
const staff = ({ user }) => ['admin', 'front-desk'].includes(user?.role)

{ slug: 'bookings',
  fields: [
    { name: 'customer', type: 'relationship', to: 'customers' },
    { name: 'service', type: 'relationship', to: 'services' },
    { name: 'startsAt', type: 'date', required: true },
    { name: 'status', type: 'select', options: ['waiting', 'confirmed'] },
  ],
  access: {
    create: staff, update: staff,
    delete: ({ user }) => user?.role === 'admin',
  },
}
Roadmap

Six levels from CMS to AI-native backend.

3 levels are complete and 3 have parts shipped. Each one says what works today and what is still to build.

  1. Level 1

    Headless CMS

    Content, drafts, versions, Thai and English.

    Complete
  2. Level 2

    Backend as a service

    Database, sign-in, files, realtime.

    Complete
  3. Level 3

    App framework

    Typed config, hooks, roles, actions.

    Complete
  4. Level 4

    Business engine

    Shop, tenants, forms. Kanban and templates next.

    Building next
  5. Level 5

    Durable workflows

    Job queue and retries. Long workflows next.

    In progress
  6. Level 6

    AI-native

    AI plugin, MCP preview. Agent approval next.

    In progress
Proven in production

Fast at a million documents. Stable since 1.0.

Every night a load test runs Easy CMS against 1,000,000 posts. The times are p95: 95% of requests finish faster.

posts in one collection
1,000,000
a post by id or slug
27ms
the next page by cursor, however deep
37ms
Thai text search with a trigram index
79ms

Easy CMS 1.15 · median of 3 runs · Postgres 17 · GitHub runner, 4 cores · 20 requests at once · 28 Oct 2026

Not everything is fast yet: a page picked by number deep in the list takes seconds (use cursor instead), and so do queries inside blocks. The full results list them. All results and how they are measured

1.0

Stable since 1.0

  • Breaking changes come only in a major release, each with an upgrade guide.
  • A renamed API keeps working until the next major, with a warning.
  • Every change is tested against databases made by older releases, on SQLite and Postgres.
  • Security fixes reach the previous major for six months after the next one is out.
What the promise covers
Questions

Before you pick a backend.

What developers ask before they bet a project on Easy CMS. Anything else, ask in GitHub Discussions.

Is it ready for production?

1.0 shipped on 17 October 2026 and releases follow semantic versioning: a breaking change waits for a major version and comes with an upgrade guide. A load test runs every night against a million posts.

Which databases and runtimes does it support?

SQLite, Turso and Postgres. It runs inside Next.js or Nuxt, or as its own server on Node.js, Bun, Deno or Cloudflare Workers.

Is it really free? What is the catch?

Every feature is MIT licensed, including single sign-on, field permissions, the audit log and backups. There is no paid edition. You run it on your own infrastructure.

Do I need Next.js or Nuxt?

No. easy-cms serve runs it as its own server, with REST and an optional GraphQL API for a Vite, React, Vue or static frontend.

Can I move from Payload or Strapi?

There is no import tool yet. Collections are TypeScript, so they map across field by field, and a script can load the data with cms.create().

Who maintains it, and what if it stops?

Easy CMS is an independent open-source project built in the open on GitHub. Your data is in ordinary tables in your own database and the code is MIT, so you can fork it or read the data without Easy CMS.

Build the backend once. Ship any app on it.

Scaffold a project with Easy CMS in about a minute. It is MIT licensed and runs on your own infrastructure.