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.
Start here
Generate a token
Mint a scoped, revocable API token in Settings → API Tokens. Shown once, hashed at rest.
Connect your AI assistant
Point Cursor, Claude Code, Windsurf, or Codex at AGENTS.md and edit your site by prompt.
Deploy your site
Take a site you built locally to a production server: fresh install, then restore your content.
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_htmlLaptop, 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.
- 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.
- 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.
- 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.
- 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.
- 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=cpanelGood 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 andcavecms updatework 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 statusCheck for a new release (changes nothing)
cavecms update --checkInstall the latest release
cavecms updateRoll back to the previous version
cavecms rollbackProgrammatic 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 →- 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.
- 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.
- 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.
- 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.
- 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.
Getting started
Install in twenty minutes
Provision a database, run `npx create-cavecms`, paste an nginx/Apache vhost, walk the eight-step browser wizard. Done.
Pick a starting palette
Ship with the signature obsidian / champagne palette out of the box. Tune any of the six core color tokens from Settings → Branding.
Browse the section library
Thirty-plus blocks (hero, gallery, channel cards, FAQ, pricing, contact form, and more) that any page can compose from.
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
SoonCart, checkout, orders, refunds, and webhook-driven payment confirmation across both processors. Coming in v1.x. Reach out if you need it sooner.
Keep going
Related
API reference
The complete CaveCMS HTTP API. Authenticate with a token, read your content, and edit a whole page in one batched request.
MCP server
Connect Claude Code, Cursor, or Windsurf to your live site with the MCP server built into every install. One command, scoped tokens, typed tools.
AI agents
Point Cursor, Claude Code, Windsurf, or Codex at your site: what AGENTS.md is, how to mint a token, and how to make your first change by prompt.
Did not find what you needed? Tell us.