postgres-native, not postgres-backed
your content lives in real Postgres tables you can query, index, and back up. no proprietary store, no lock-in — point psql at it and read.
schema-as-code, draft-vs-published clarity, and content in plain Postgres tables. open source, Apache-2.0, self-host free forever.
pepper migrate --from hygraph
reading hygraph schema and fields
mapping to chili.config.ts (schema-as-code)
writing migrations + RLS policies
generated an import plan for review
done. your content runs on your Postgres now.
the schema is canonical in code, not clicked together in a GUI you can't review. you write models, fields, and relations in chili.config.ts, and the Studio generates the editing UI from that file.
schema changes ship the way code ships. they land in a pull request, get reviewed, and run as a migration. no drift between what an admin clicked last quarter and what your repo says is true.
nothing goes live by accident. each save writes a draft, and the entry stays in draft until an editor publishes it on purpose. the published state carries a real green colour, a filled dot, and a "live" label, so status never rides on colour alone.
scheduled publishing and preview tokens let a content lead stage a launch. an editor sees what is live across thirty entries at a glance, and a typo never ships because someone hit the wrong button.
editors edit against the rendered site, not a raw form in isolation. the canvas is a 55/45 split: the form on the left, your actual site rendering on the right, updating as they type.
the preview renders the customer's site. our Studio chrome never bleeds into that pane, so what an editor sees is what a reader gets.
REST is the stable delivery path today. GraphQL covers the built-in content graph, and the SDK gives you a generic typed helper while generated per-model clients mature.
the schema still has one source of truth: chili.config.ts. as generated clients land, they should come from that same file instead of a second API description.
every tenant table runs FORCE ROW LEVEL SECURITY. the database refuses to return another tenant's rows even if the application asks, so isolation does not depend on a where-clause someone might forget.
middleware sets app.tenant_id per transaction from a verified JWT, and the policy does the rest. one project can host many tenants on one Postgres without trusting application code to stay perfect.
the model you write in code drives the editor, the API, and the isolation — no second source of truth.
your content lives in real Postgres tables you can query, index, and back up. no proprietary store, no lock-in — point psql at it and read.
REST is the stable delivery path today. GraphQL covers the built-in content graph, and the SDK gives a typed helper while generated per-model clients mature.
Apache-2.0 core, no feature paywall. one container plus your Postgres. deploy it on a $40 box and keep your data.
tenant isolation is enforced in Postgres with FORCE ROW LEVEL SECURITY, not in app code you have to trust.
a real rich-text editor on Tiptap. every save is a draft; nothing goes live until you publish it.
the Studio keeps gradients out of data surfaces so repeated editing stays calm. your content path is one app container plus Postgres.
the same published post over REST, GraphQL for the built-in content graph, and the generic SDK helper.
curl https://api.chilicms.dev/v1/posts \
-H "Authorization: Bearer $CHILI_TOKEN"query Posts {
posts(status: PUBLISHED) {
id
title
publishedAt
}
}import { createClient } from "@chilicms/sdk"
const chili = createClient({ baseUrl: "https://api.chilicms.dev" })
const posts = await chili.list<{ title: string }>("posts")we mark where we lose, not just where we win. our cloud is younger and our plugin marketplace is smaller — both are honest gaps.
| capability | ChiliCMS | Contentful | Hygraph | Strapi |
|---|---|---|---|---|
| schema-as-code, version-controlledthe content model lives in your repo | ||||
| self-host free foreverApache-2.0 core, no feature paywall | ||||
| runs on your own Postgresno proprietary datastore | ||||
| REST + GraphQL + SDK | ||||
| row-level-security multi-tenancyenforced in the database, not app code | ||||
| hosted cloud maturitywhere we lose today — our cloud is younger | ||||
| marketplace of pluginsanother honest gap — Strapi's is larger |
In real Postgres tables in your own database. You can point psql at it, index it, and back it up like any other table. There is no proprietary store in front of it, so leaving ChiliCMS does not mean exporting from a black box.
You edit chili.config.ts and open a pull request. The diff reviews like any code change, then runs as a migration. The Studio generates its editing UI from that file, so the GUI never becomes a second, unreviewed source of truth.
No. REST is the stable delivery path today, GraphQL covers the built-in content graph, and the SDK exposes a generic typed helper. Generated per-model clients are the intended next step, not something we pretend is already complete.
Every tenant table runs ENABLE plus FORCE ROW LEVEL SECURITY. Middleware sets the tenant id per transaction from a verified JWT, and the policy filters every read. Isolation does not depend on app code remembering a where-clause.
Self-hosting the Apache-2.0 core is free forever. The hosted cloud is priced on workspace shape (members, environments, locales, entries), not on API calls, and the Enterprise floor is printed publicly on the pricing page. No per-call metering, no contact-us wall under $5k.
Schema-as-code, draft-until-published clarity, and REST-first delivery. Apache-2.0, self-host free forever.