TEditable primitives
Inline text with a rich-text toolbar, images, video, icon lists. Paste a YouTube, Instagram, or Maps link — it becomes the right embed. One path prop each.
Open source · MIT · copy-in, you own the code
CMSBar is a Git-as-CMS bar you drop into your own codebase — five React hosts (Next.js, React Router 7, TanStack Start, a Vite SPA, Astro) plus native SvelteKit and Nuxt UIs on the same protocol. Editors click anything on the page and change it in place — every save becomes a branch and a PR in your repo. No database, no dashboard to host, no vendor.
Extracted from production. ~50 files copied into your repo — delete it any time and your content is still just JSON in Git.
Open daily from 7am
Small-batch loaves, baked in Osijek every morning.
Order for pickup↑ A pixel-for-pixel preview of the real workflow: one draft = one branch = one PR = one version. Open the live playground to try it for real.
In 22 seconds
How it works
Editors log in on the live site. Every wrapped element — <T path="home.hero.headline"/> — gets an editing ring. Click it, type. Images, video, rich text, lists: same gesture.
All changes batch into one commit on a cms/* branch via the GitHub Git Data API. Unsaved work survives reloads — localStorage for text, IndexedDB for uploads.
Each draft is an open PR titled [CMS draft] …. Preview any branch live, fork it, or lock it with an approved label. It's just Git — your reviews, your CI, your history.
Merging redeploys with the new content baked into the build. The production container never writes to disk — restart it, lose nothing.
Works with your framework
A framework-neutral core (~64% of the code, untouched per host) plus a thin per-host seam: one client host (pathname, navigate, image, apiBase — with DOM defaults) and one server mount. The whole API is a single dispatcher — handleCmsRequest / createCmsApi — mounted as one catch-all route. The seam is frozen and validated across all five React hosts; a 156-test handler-level harness backs it. Two non-React UIs — SvelteKit (Svelte 5) and Nuxt (Vue 3) — reuse that same core + handlers, with the component layer rebuilt natively.
Each shipped host has a live example in the repo that builds and runs: examples/.
$ npx cmsbar new my-site --framework astro
$ npx cmsbar init --framework react-router
Per-framework quickstarts and the host seam live in the docs; the non-React contract is in docs/PROTOCOL.md, and every host has a runnable example.
The mental model
Publishing
Every save opens a pull request — that's the default, and for client work it's the point. But not every site needs review. One config key makes Save commit straight to the base branch instead: no draft, no PR, deploy on save.
One line in cms.config.ts. Flip it back the day the stakes change.
What's in the box
Inline text with a rich-text toolbar, images, video, icon lists. Paste a YouTube, Instagram, or Maps link — it becomes the right embed. One path prop each.
Toolbar output is styled out of the box — headings, lists, and editable links via .cmsbar-prose, declared in @layer base so your site's CSS always wins.
Drag the focal point on any cropping image — media slots included. The library browses your repo's folders: create, upload, delete, all staged into the same save.
Define onboarding steps in cms.config.ts; <CmsTour/> spotlights each one. Auto-starts once per editor, re-runs from the ✦ Guide pill in the bar.
Multiple drafts in flight, live preview of any branch, fork from any version, approval label locks a draft read-only.
All writes go through the GitHub API with a fine-scoped PAT. The container is disposable; unsaved edits live in the editor's browser.
cms.config.ts owns namespace, content file, media folders, branch prefix, pages, shared-content rules. No magic strings.
Every color in the editor chrome is a --cmsbar-* CSS variable. Re-brand the whole experience from one stylesheet.
bcrypt + HMAC session cookie, rate-limited login, shared-element warnings, per-page SEO drawer, optional pre-launch teaser gate.
Install
shadcn-style: the CLI copies the source into your project and gets out of the way. There is no runtime dependency on CMSBar — fork it, theme it, delete it. Starting fresh? npx cmsbar new my-site --framework <fw> scaffolds a host and assembles the core. Below: adding it to an existing Next.js app.
$ npx cmsbar init --namespace bakery
✓ 55 files copied (components/cmsbar, lib/cmsbar, app/api/cms, …)
✓ cms.config.ts written — namespace "bakery"
✓ env keys appended to .env.example
Next: wrap your layout, import the theme, add a PAT.
Then make anything editable:
<T path="home.hero.headline" as="h1" />
Cloud Studio
The hosted control plane for agencies running CMSBar across many client repos. In development — a demo seeded with sample projects already runs. The OSS core never depends on it.
Pricing
Self-host everything, forever, free. The hosted control plane — for agencies who'd rather not run token custody, client logins, and previews themselves — is in development.
$0 MIT, forever
$ projects × editor seats
$$ for agencies
FAQ
In content/site-content.json in your repo, imported at build time. Drafts are branches; merging redeploys. Your content's full history is git log.
Your site keeps rendering the same JSON — the primitives render bundled values when no editor is logged in. Delete the components and inline the strings whenever you like. There's nothing to migrate off.
No. Editors log in with a username/password on your site; the server holds one fine-scoped PAT. (Hosted client identity with magic links is what Cloud Studio adds.)
Uploads stage in the browser (IndexedDB), then commit as blobs in the same PR as the text changes. Folder allowlists are configured in cms.config.ts.
Five React-family hosts ship today, each with a live example that builds and runs: Next.js (App Router), React Router 7, TanStack Start, a Vite + React SPA (with a small Hono companion server), and Astro (React islands). Beyond React, SvelteKit (Svelte 5) and Nuxt (Vue 3) now ship as native UIs on the same protocol — full feature parity, browser-verified — so all seven scaffold with npx cmsbar new --framework <fw>. See the frameworks matrix and docs/PROTOCOL.md (the non-React contract). A pure SPA still needs a tiny server for the write token — that's the companion server, not a browser-held token.
CMSBar was extracted from a production site where it ships real content edits as PRs daily. The standalone package is young — pin a commit, read the code (it's yours), and file issues.