CaveCMS
Documentation

A hand-coded site.
With a CMS anyone can edit.

CaveCMS gives a Next.js site the speed and polish you’d hand-code, plus a CMS your clients or your AI agents can edit in the browser. Install, edit, deploy, and drive it over a real API. Pick a topic on the right, or start at the beginning and walk through.

First time

The four-step install guide

The fastest way to see CaveCMS running on your own server.

Quick install

One command,
either path.

The full walkthrough lives on /get-started. Below: the one command each path needs. Click copy, paste in a terminal, finish in the browser wizard.

VPS, production

Edit the highlighted fields below before you copy. The copy button bakes your values into the snippet, so there is no fumbling at the terminal prompt to fix placeholders after paste.

npx create-cavecms@latest  \
  --surface=pm2 --port= \
  --dir=/var/www/html//public_html

Laptop, local evaluation

Edit the highlighted fields below before you copy. The copy button bakes your values into the snippet, so there is no fumbling at the terminal prompt to fix placeholders after paste.

npx create-cavecms@latest  --surface=laptop --port=

Shared hosting

Install on cPanel.

No VPS, no sudo, no nginx. On any CloudLinux cPanel host with the Node.js Selector (Namecheap, A2, HostGator), CaveCMS installs through the Setup Node.js App screen plus a single terminal command, served by Passenger. The click-by-click walkthrough lives on /get-started under the cPanel tab.

cPanel is a newer install target than a Linux VPS. Skim the good to know notes before you put a client site on shared hosting.

  1. 01

    Create the database

    cPanel → MySQL® Databases: create a database, create a user with a strong password, then add the user to the database with ALL PRIVILEGES. Both names get an account prefix (e.g. myacct_cavecms), so keep the full names + password for the installer.

  2. 02

    Create the Node.js app

    cPanel → Setup Node.js App → Create Application. Pick Node 20+, set the application root to cavecms, and your domain as the application URL.

  3. 03

    Run the installer in Terminal

    cPanel → Terminal. Paste the "Enter to the virtual environment" line cPanel shows for the app (so node + npx resolve). Creating the app seeded the folder with placeholder files (visible and sometimes hidden), so clear them all first, then run the command below. At the prompts, keep the DB host as 127.0.0.1 and press Enter for the app listen port (Passenger assigns the real one). It downloads + signature-verifies the signed release, generates every secret, seals env.production with your database, runs migrations, and writes the app.js Passenger entry.

  4. 04

    Point Passenger at it

    Back in Setup Node.js App: set the Application startup file to app.js, do NOT click "Run NPM Install" (dependencies are bundled in the release), then Restart.

  5. 05

    Finish in the browser

    Open https://your-domain.com/install (the installer printed the same URL with a one-shot token) and walk the wizard (admin account, branding, SMTP, security).

Step 3: clear the seeded files (incl. hidden), then install (cPanel → Terminal)

find ~/cavecms -mindepth 1 -delete
npx create-cavecms@latest cavecms --surface=cpanel

Good to know on shared hosting

  • Image processing needs a current CloudLinux. CaveCMS bundles the Linux image processor (sharp). It loads fine on modern CloudLinux 8/9. Very old shared boxes (CloudLinux 7 / glibc < 2.26) can fail to load it. Choose a Node 20+ plan on a current CloudLinux, or use a VPS.
  • Database host is 127.0.0.1, not localhost. When the installer asks for the database, use 127.0.0.1, because the MySQL driver treats the literal “localhost” as a Unix-socket path that rarely matches cPanel's socket.
  • Never click “Run NPM Install”. Every dependency ships inside the signed release. Re-installing on the box can clobber the bundled native binaries.
  • Restarts go through Passenger. After an update or config change, use Setup Node.js App → Restart (or touch ~/cavecms/tmp/restart.txt). The in-app updater and cavecms update work the same here.
  • HTTPS is your host's free certificate. AutoSSL on most cPanel hosts; on Namecheap shared use the free “Namecheap SSL” plugin (AutoSSL is VPS/dedicated only there).
  • Old site still showing, or a 503? If the domain previously ran WordPress or another site, or you hit “Service Unavailable,” the cPanel troubleshooting section has the exact fix.

Updates & recovery

Stay current.
Undo in one command.

New releases show up as a banner in your admin (Settings → Updates). Click Update now and a guided six-step install runs with a safety net: if the new version does not come up healthy, CaveCMS puts the old one back on its own. Prefer the terminal? The same engine runs from a shell, and cavecms rollback is your one-command escape hatch.

The cavecms shortcut is set up at install time. If it is not on your PATH, run ./cavecms <command> from your install directory, or npx create-cavecms@latest <command> from anywhere.

cavecms update --version=X.Y.Z pins a specific release (re-install or downgrade); cavecms update --force re-installs the current version to recover a broken build; cavecms help lists everything.

See what's running

cavecms status

Check for a new release (changes nothing)

cavecms update --check

Install the latest release

cavecms update

Roll back to the previous version

cavecms rollback

Programmatic editing

Edit with AI agents.
Or any HTTP client.

CaveCMS ships a real HTTP API. Generate a token in Settings → API Tokens, send it as a Bearer header, and an AI coding tool (Cursor, Windsurf, Claude Code, OpenAI Codex) or any script can read and edit your site: pages, posts, the section → column → widget block tree, media, and branding. Lightning fast, with the visual builder still right there when you’d rather click.

Token requests skip the cookie + CSRF flow entirely; the token is the credential. Hand your agent the token plus the endpoint reference, and it drives the API for you.

Read the full API reference →
  1. 01

    Generate a token

    Settings → API Tokens → Create. Pick a role (editor or admin) and an optional expiry, re-enter your password, and copy the token. It is shown exactly once, then kept only as a SHA-256 hash. Lose it and you simply revoke + mint a new one.

  2. 02

    Authenticate

    Send Authorization: Bearer cave_… on every request. No cookie, no CSRF token, no login page. Confirm you are in with a read: GET /api/cms/pages returns 200 with a token, 401 without one.

  3. 03

    Read, then write

    GET /api/cms/pages/{id} returns a page with its full section → column → widget tree, where every block carries a version and its meta (a section’s background, padding, columns live here). GET /api/cms/posts/{id} and /api/cms/projects/{id} return a single post or project to read before editing. POST / PATCH / DELETE under /api/cms/* create, edit, reorder, duplicate, restore, or soft-delete blocks, pages, posts, and media. PATCH /api/admin/settings changes branding, theme, SEO, header, and footer.

  4. 04

    Go fast: batch many edits in one call

    POST /api/cms/pages/{id}/batch applies many ops (create with temp-ids to build whole trees, patchData, patchMeta, delete, reorderChildren) in ONE request and ONE transaction. Version numbers are OPTIONAL (omit for last-write-wins, exactly like a direct DB write); partial-merge ops like metaPatch:{ background:"obsidian" } change one field without reading the rest first. “Recolor 12 sections and retitle 5 headings” becomes a single round-trip: as fast as touching the database, but fully validated, sanitized, and audited.

  5. 05

    Hand it to your AI tool

    Every install ships an AGENTS.md at its root: the agent-facing guide that Cursor, Claude Code, Windsurf, Codex, and Aider read automatically (how to authenticate, the exact endpoints, what is off-limits). After install, point your AI tool at AGENTS.md, give it the token, and describe the change in plain English. It composes the API calls and your live site updates in seconds.

Read, then batch-edit (Authorization: Bearer cave_…)

# read a page + its block tree (each block carries its meta + version)
curl https://your-site.com/api/cms/pages/42 \
  -H "Authorization: Bearer cave_YOUR_TOKEN"

# many edits in ONE call — recolor a section, retitle a heading,
# add a new one — applied in a single transaction. No CSRF, no cookie.
# Versions optional (omit = last-write-wins); metaPatch merges one field.
curl -X POST https://your-site.com/api/cms/pages/42/batch \
  -H "Authorization: Bearer cave_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ops":[
    {"op":"patchMeta","blockId":101,"metaPatch":{"background":"obsidian"}},
    {"op":"patchData","blockId":205,"dataPatch":{"text":"New headline"}},
    {"op":"create","kind":"widget","blockType":"lx_heading","parent":108,
     "data":{"text":"Hello, world","alignment":"center"}}
  ]}'

What a token can & can’t do

  • Scoped. Each token carries one role (editor or admin) chosen when you create it.
  • Capped to content & branding. A token can edit pages, posts, blocks, media, and branding/theme settings, and never user accounts, security/auth settings, secrets, analytics injection, or the updater. That holds even for an admin-role token.
  • Revocable, instantly. Revoke a token in Settings → API Tokens and it returns 401 the same second. Set an optional expiry, and deleting the person who created it kills their tokens too.
  • Shown once. The secret appears a single time at creation; CaveCMS stores only a hash. It can never be displayed again.

Going live

Deploy to production.

Built a site on your laptop and want it live, maybe on a server that already hosts other apps? The content-preserving deploy: a fresh install on the server, then restore your local backup over it. The full, verified runbook (recon, backup, install, restore, vhost, TLS, and the end-to-end checks) lives on its own page.

Content-preserving

Fresh install, then ./cavecms restore brings your pages, media, settings, and admin, so the wizard never runs.

Shared-server safe

Mirror an existing install’s PM2 user + a per-domain vhost so you never clobber a sibling site.

No secrets travel

The backup carries content + media only; the server keeps its own sealed env.production.

Verify by assertion

Row-count checks after restore; home 200 / wizard 404 / secrets 403 / admin → / after go-live.

System requirements

Linux: Ubuntu, Debian & any systemd distro · Recommended

Ubuntu or Debian 22.04 LTS+ (or any systemd distro) with nginx or Apache. x64 or ARM. 1 GB RAM minimum, 2 GB recommended. Tested on Ubuntu 22.04 LTS, the recommended way to run CaveCMS in production.

macOS: Apple Silicon & Intel

Apple Silicon (arm64) and Intel (x64) both supported. Local and desktop installs run as a single foreground Node process, no nginx, no PM2. Needs Node 20+, MariaDB, and wget (brew install wget).

cPanel: Shared hosting, no root

Shared Linux hosting via cPanel’s Node.js Selector and Passenger. No root or systemd needed: the installer detects cPanel and configures the Passenger app for you.

Windows

On Windows? CaveCMS runs inside WSL2 + Ubuntu, which behaves exactly like a Linux server. Native Windows isn’t a deployment target.

Versions & tooling

Node 20 or newer, and MariaDB 10.11+ (10.6 is the hard minimum; pure MySQL isn’t supported). wget, unzip, and curl on PATH for install; rsync too for in-app updates and rollback. Apple Silicon, Intel, and ARM all run. 1 GB RAM minimum, 2 GB recommended.

Editing your site

Live, in-place editing, with safe drafts

Click any word on any page and edit it. Every change autosaves to a private draft, with no Save button. Visitors keep seeing the existing published page until you publish your new changes; close the tab and your draft is right where you left it, with full undo and redo.

Drag-and-drop sections

Pick up any section by its handle. Drop it elsewhere on the page, into another column, or onto a different page entirely. Native touch support via @dnd-kit.

Media library with auto-variants

Upload an image once. CaveCMS auto-generates thumb (320w), md (768w), lg (1600w), and og (1200×630) variants via sharp. Re-use the same media on as many pages as you want.

Slash commands

Type "/" anywhere on a page to drop a new block: heading, image, gallery, quote, CTA, anything in the library.

AI writing partner (beta)

Highlight anything on the page. Ask AI to rewrite, translate, suggest, or fill in. Powered by Google Gemini through your own API key, so your text never touches our infrastructure.

Edit with AI agents (the HTTP API)

Generate a token in Settings → API Tokens, send Authorization: Bearer, and let Cursor, Claude Code, Windsurf, or Codex drive your live site through the API or CaveMCP, no browser required. Scoped, capped, revocable. See the AI agents guide →

Section templates

Eight ready-made section starters (hero, FAQ, pricing, contact, team, projects, quote-wall, hero-stats). Drop one onto any page, customise inline.

Where to host

A small Linux VPS

1 GB RAM minimum, 2 GB recommended. Tested on Ubuntu 22.04 LTS. Hetzner CX22, DigitalOcean Basic, Linode Nanode, Vultr, anything modern works.

One install command

`npx create-cavecms@latest <site> --surface=pm2 --port=<port> --dir=<path>` downloads the latest signed release, verifies the SHA + Ed25519 signature, generates every secret, seals an env.production (mode 600), runs migrations, and starts the app under PM2. Ninety seconds.

nginx OR Apache

The installer prints a vhost block at the end. Or run the bundled `scripts/install-nginx.sh` / `scripts/install-apache.sh` to drop in a vhost with security headers + rate limits + Let's Encrypt-friendly defaults.

cPanel & shared hosting

No VPS? CaveCMS installs on shared cPanel hosting (Namecheap, A2, HostGator) through the Node.js Selector + Passenger: MySQL® Databases for the DB, one terminal command for the app. Read the cPanel guide →

Built-in updater

Every release shows as a banner in the admin. Click Update Now and a six-step modal (preflight → fetch → install_migrate → build → restart → verify) handles download + signature verification + migrate + atomic swap. Auto-rollback if the post-flight `/healthz` poll fails.

Security baseline

Hidden admin URL

Every install gets a random 12-char admin path. The middleware refuses to leak it in any redirect or error message, so admin discovery is impossible from public surfaces.

JWT + CSRF + rate limits

Session tokens are HS256 JWT (8h max, jose library). CSRF on every state-changing endpoint (HMAC-SHA256, dedicated CSRF_SECRET). Login endpoints rate-limited per-IP AND per-email with progressive lockout.

CSP with strict-dynamic

Per-request nonce. No `unsafe-eval` in production. Integration CSP allow-lists are operator-toggled: flip off Hotjar and its origins disappear from the policy at the next request.

Sealed env.production

Bootstrap secrets are generated once by the CLI and written with mode 600 ownership. Operators never edit env files by hand; all subsequent config flows through the `settings` table via the admin UI.

Going further

Integrations, no code

Settings → Integrations covers Google Tag Manager, GA4, Google Ads, Hotjar, Zoho SalesIQ, and HubSpot Tracking. Paste an ID, toggle on. Zoho CRM available as a server-side lead-forwarding destination.

Add a new kind of section

Four files: Zod schema in `lib/cms/block-registry.ts`, admin metadata in `lib/cms/blockMeta.ts`, React renderer in `components/blocks/<Name>/render.tsx`, optional seed. Every shipped section follows the same pattern, and the one you ship plugs in the same way.

Fair-source licensed

Prosperity Public License 3.0.0. Free for personal, hobby, and non-profit use forever. Thirty-day commercial trial. Single licence fee for ongoing commercial use.

Industry-specific templates

Hotel, real-estate, church, restaurant, software, freelance, wellness, and design-studio: eight full polished starter sites, each picked from the install wizard. The CaveCMS welcome one-pager is still the default for operators who want a clean slate.

E-commerce with Stripe + Paystack

Soon

Cart, checkout, orders, refunds, and webhook-driven payment confirmation across both processors. Coming in v1.x. Reach out if you need it sooner.

Did not find what you needed? Tell us.