Why we put the CMS inside your app
A hosted headless CMS is a second service with its own deploy and database. Easy CMS is a package your app mounts instead. Here is what that changes.
Most headless CMSs are a separate service. Your site calls it over HTTPS with a token, and you keep two deployments, two databases and two sets of credentials in step. Easy CMS takes the other route: it is an npm package that runs inside your Nuxt or Next.js server.
One app, one database
The admin at /admin and the REST API at /api/cms are routes of your app. Your pages read content with the Local API, a function call in the same process, with no HTTP involved. Content lives in your database, SQLite or Postgres, in real tables and columns with an ecms_ prefix, so you can still query it with SQL.
The content model is code
Collections, fields, access rules and hooks go in easy-cms.config.ts. You review changes in pull requests, and production gets them as migrations you can read before they run.
const cms = await getEasyCMS(config)
const { docs } = await cms.find('posts', { limit: 10 })
// docs[0].title is a string, typed from the configTyped without a build step
Because the config is TypeScript, cms.find('posts') returns typed documents straight from it. There is no schema to download and no code generation to keep up to date.
The trade-offs
Editors can't change the content model themselves; a developer changes the config.
It needs Node.js 22.12 or newer, so no edge runtimes.
There is no GraphQL, and the plugin ecosystem is young.
If you build with Vite, React, Vue or a static site generator, the same core runs as a standalone server with REST.