A portable, files-first headless CMS. Content lives as JSON files in a bucket (S3, R2, or local filesystem) and is the source of truth. A database next to the admin holds a query-fast projection of the bucket (rebuildable from the bucket) plus operational state (sessions, tokens, jobs — not rebuildable). Frontends read the bucket directly; the database is never on the read path. The bucket layout is the protocol.
Thoughts, questions, or interested in contributing? Email [email protected] with details — happy to chat about what you're trying to build or where clear could fit. I'll review whatever's submitted either way; GitHub Issues / PRs / Discussions all work too if that's easier. :)
clear ships out of two physical repos:
clearcms/clear— this repo. The OSS distribution (MIT). The admin editor, the protocol spec, the consumer SDK, the Astro adapter, the scaffolder, and the single-instance CLI. Published to npm under@clearcms/*.clearcms/cloud— the closed-source hosted-service code. The operator console (multi-project orchestration, identity bridging across instances). Consumes@clearcms/adminfrom npm; nothing closed lives here.
The split was operationalised in ADR-0014. You don't need the cloud repo to self-host.
You don't clone this repo. Run the scaffolder:
npx @clearcms/create my-site
cd my-site
pnpm install
pnpm devYou get an Astro frontend wired to a local bucket and a clear admin running side-by-side on :3001 and :4321. The first run prints an owner password — save it.
Scaffold a clear project alongside the existing one, then point the importer at the Astro content.config.ts:
npx @clearcms/create my-site
cd my-site
pnpm install
pnpm exec clear-admin import ../my-existing-astro-app \
--from-astro-config=../my-existing-astro-app/src/content.config.tsThe importer parses the Astro zod schema, derives matching collections + fields in the bucket schema, and walks every collection ingesting both .md/.mdx and .json. Bilingual files following the <slug>.<lang>.<ext> Astro convention are split into per-locale rows. The Astro frontend can then either keep using its existing source for now or switch its loader to @clearcms/astro to read from the bucket — see docs/integrations/astro.md.
clear is framework-agnostic. The admin runs as a standalone service; your frontend talks to it via REST or SDK.
cd my-nextjs-app
npm install -D @clearcms/admin
npm install @clearcms/sdk
npx clear-admin bootstrap # creates ./data/storage + ./data/clear.db, seeds owner
npx clear-admin start # admin UI on :3001
# in your code:
import { createClient } from '@clearcms/sdk';
const cms = createClient({ backend: 'rest', adminUrl: 'http://localhost:3001' });
const posts = await cms.collection('posts').list();clear-admin is the only OSS CLI (ADR-0018). Its subcommands — start, bootstrap, migrate, import, scaffold, reindex, sync-pages, doctor, config, env, reset-password, sync-media, find-unused-media — operate on the bucket and DB directly with no framework dependency.
Three places. That's it.
my-site/data/storage/ ← content + media. Yours. Portable. Gitable. (the bucket)
my-site/data/clear.db ← projection of the bucket (rebuildable via `clear-admin reindex`)
+ operational state (sessions/tokens/jobs — not rebuildable).
my-site/ ← your frontend code (Astro, Next, whatever).
The OSS distribution is single instance per install — one site, one bucket, one admin. If you want N sites managed in one place with shared identity, that's the cloud console (closed-source).
apps/
└── admin/ @clearcms/admin — the editor app (Astro). Ships the
`clear-admin` CLI bin (the single CLI surface; see
ADR-0018).
packages/
├── spec/ @clearcms/spec — protocol contract (JSON Schemas, types)
├── sdk/ @clearcms/sdk — typed consumer client (fs/r2/s3/rest)
├── astro/ @clearcms/astro — Content Layer adapter
├── index/ @clearcms/index — DB-from-bucket rebuilder
├── core/ @clearcms/core — env loaders + shared utilities
├── db/ @clearcms/db — Drizzle schema + libSQL client
├── storage/ @clearcms/storage — bucket adapters (fs, R2, S3)
├── design/ @clearcms/design — shared brand tokens (placeholder)
├── mcp/ @clearcms/mcp — MCP server (experimental)
└── create-clear/ @clearcms/create — scaffolder (npx target)
The admin renders the editor surface from a JSON schema, not from a hardcoded layout (ADR-0020). Two modes:
form(default) — 2-column grid generated from the schema. Use it for structured content (contact pages, recipes, team members). TipTap is one widget (widget: "richtext") — not the canvas.article— full-canvas TipTap, opt-in viaeditor: "article"on the schema. Use it for long-form prose like blog posts.
Schemas live in the bucket alongside content:
data/storage/
├── schemas/<collection>.json ← collection schema (items)
└── theme/layouts/<layout>.schema.json ← page layout schema (pages)
Per-page structured data lives next to the page document at content/pages/<slug>/data.json (ADR-0010, v1 abridged). The SDK reads it across all four backends:
const home = await cms.pages.get('home');
home?.data; // { hero: {...}, ctaUrl: '...', features: [...] }
const post = await cms.collection('posts').get('hello');
post?.data.title; // string
post?.data.body; // ProseMirror JSONSee docs/integrations/astro.md for the full Astro wiring.
STATE.md— live "what's true right now" snapshot. Read first — memory and old ADRs go stale.ROADMAP.md— what's recently shipped + what's coming next.CONTEXT.md— domain language. Canonical for terminology.docs/adr/— architecture decisions in order. Read before proposing structural change.docs/CONTENT-PROTOCOL.md— bucket layout + REST contract as wired today.AGENTS.md— agent-targeted reading guide.ARCHITECTURE.md— concise architectural overview.
Pre-1.0. All @clearcms/* packages on npm at 0.2.x. v0.3 is in flight (schema-first editor — see the queued changeset in .changeset/). v1.0 cuts when CLI parity + docs rewrite ship.
For per-package versions and what's shipped vs. proposed vs. in-flight, STATE.md is the single source of truth. For per-package release history, look at each package's CHANGELOG.md (managed by Changesets).
OSS distribution under MIT. Hosted-service code (in clearcms/cloud) is closed and not licensed for redistribution.