Skip to content

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.

  • Node 20+ and npm 10+ (or pnpm 9+ / yarn 4+)
  • An existing Astro 5 or 6 project (or a blank npm create astro@latest)

Keep Astro’s default static output. No SSR adapter. Public visitors see edits after Publish → rebuild → deploy.

Full guide: Static delivery.

  1. Install the package

    Terminal window
    npm install @caretcms/core

    Server delivery also needs an adapter, e.g. npm install @astrojs/node.

  2. Add the integration

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import caret from '@caretcms/core';
    export default defineConfig({
    integrations: [caret({ delivery: 'static' })],
    });

    Or run npx @caretcms/caretize init to install and wire CaretCMS automatically — then npx @caretcms/caretize to tag existing markup. See Caretize CLI.

    Defaults: admin at /admin, API at /api/cms, uploads at public/uploads/. Storage is filesystem (.caret/data/) unless CaretCMS detects Astro content collections under src/content/ — then it picks markdown storage automatically. See Storage adapters and Configuration.

  3. 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 src on 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.

  4. Set the editor password

    .env
    CARET_EDIT_PASSWORD=devpass
    CARET_SESSION_SECRET=replace-with-a-long-random-string
    Terminal window
    npm run dev

    With 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'))"
  5. Edit

    1. Open http://localhost:4321/admin and log in with the password.
    2. Go back to your homepage.
    3. Click any annotated text — it becomes contenteditable. Hit Enter or click outside to save.
    4. Click an annotated image — an upload dialog opens. Pick a file; it uploads and the src updates.
    5. Reload — your edit persists.
    6. In dev, open Astro’s Dev Toolbar → CaretCMS to highlight every binding on the page (no login required).

You also get:

JSON under .caret/data/:

  • Directory.caret/data/
    • Directorypages/
      • home.json created on first save
    • Directorysite/
      • global.json
  • Directory.caretcms/
    • revisions.json
    • Directoryhistory/
    • Directorycollections/

Collections and directories are created on first write. To git-track JSON content, point dataRoot at a folder inside src/ (see Storage Adapters).

For more, see Troubleshooting.