Quickstart
Five steps to a site where you can click text and images to edit them.
This guide is for adding CaretCMS to an existing Astro project. Starting fresh? Clone examples/starter from the CaretCMS repo and skip to step 4.
Prerequisites
Section titled “Prerequisites”- Node 20+ and npm 10+ (or pnpm 9+ / yarn 4+)
- An existing Astro 5 or 6 project (or a blank
npm create astro@latest)
Pick your delivery mode
Section titled “Pick your delivery mode”Keep Astro’s default static output. No SSR adapter. Public visitors see edits after Publish → rebuild → deploy.
Full guide: Static delivery.
Use output: 'server' plus an SSR adapter when you need edits visible to visitors immediately (per-request middleware rewrite).
Five-minute setup
Section titled “Five-minute setup”-
Install the package
Terminal window npm install @caretcms/coreTerminal window pnpm add @caretcms/coreTerminal window yarn add @caretcms/coreServer delivery also needs an adapter, e.g.
npm install @astrojs/node. -
Add the integration
astro.config.mjs import { defineConfig } from 'astro/config';import caret from '@caretcms/core';export default defineConfig({integrations: [caret({ delivery: 'static' })],});astro.config.mjs import { defineConfig } from 'astro/config';import node from '@astrojs/node';import caret from '@caretcms/core';export default defineConfig({output: 'server',adapter: node({ mode: 'standalone' }),integrations: [caret()],});Or run
npx @caretcms/caretize initto install and wire CaretCMS automatically — thennpx @caretcms/caretizeto tag existing markup. See Caretize CLI.Defaults: admin at
/admin, API at/api/cms, uploads atpublic/uploads/. Storage is filesystem (.caret/data/) unless CaretCMS detects Astro content collections undersrc/content/— then it picks markdown storage automatically. See Storage adapters and Configuration. -
Annotate your template
By hand:
src/pages/index.astro <main data-caret-scope="pages::home"><h1 data-caret="headline">Welcome to my site</h1><p data-caret="intro">This text can be edited inline.</p><img data-caret="hero" src="/img/hero.jpg" alt="" /></main>How the binding resolves:
data-caret-scope="pages::home"sets the collection (pages) and id (home) for everything inside.- Each
data-caret="field"inside that scope binds to that field on the entry. - For images, the editor opens an upload dialog and rewrites
srcon save.
You can also write the full binding inline without a scope:
data-caret="pages::home::headline".Or scan an existing site with Caretize — it inserts bindings from your current markup.
-
Set the editor password
.env CARET_EDIT_PASSWORD=devpassCARET_SESSION_SECRET=replace-with-a-long-random-stringTerminal window npm run devTerminal window pnpm devTerminal window yarn devWith no password configured, a temporary dev password is printed in the terminal (dev only).
Generate a real session secret:
Terminal window node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))" -
Edit
- Open
http://localhost:4321/adminand log in with the password. - Go back to your homepage.
- Click any annotated text — it becomes contenteditable. Hit Enter or click outside to save.
- Click an annotated image — an upload dialog opens. Pick a file; it uploads and the
srcupdates. - Reload — your edit persists.
- In dev, open Astro’s Dev Toolbar → CaretCMS to highlight every binding on the page (no login required).
- Open
You also get:
Where edits live
Section titled “Where edits live”JSON under .caret/data/:
Directory.caret/data/
Directorypages/
- home.json created on first save
Directorysite/
- global.json
Directory.caretcms/
- revisions.json
Directoryhistory/
- …
Directorycollections/
- …
When src/content/ has Astro collections, frontmatter edits write to your .md / .mdx files on Publish. Revisions still live in .caretcms/.
Collections and directories are created on first write. To git-track JSON content, point dataRoot at a folder inside src/ (see Storage Adapters).
Common gotchas
Section titled “Common gotchas”For more, see Troubleshooting.