Skip to content

Customizing with Claude Code

Baan ships with a fully configured Claude Code environment. Clone the repository, open it in Claude Code, and it already understands the project’s architecture, conventions, and rules. No setup required.

This makes Baan uniquely suited for AI-assisted customization — not just using AI to write articles, but using AI to extend and adapt the CMS itself.

When you clone Baan and open it in Claude Code, the following are already in place:

File / DirectoryPurpose
CLAUDE.mdProject overview, tech stack, directory structure, coding principles
.claude/rules/Automatic rules loaded per file path — security, storage, theme system, i18n, API patterns
.claude/skills/Slash commands for common workflows — theme creation, build strategy, content management

Claude Code reads CLAUDE.md at the start of every session, giving it full context about how Baan works: how settings are stored, which patterns to use, what to avoid. The .claude/rules/ files load automatically based on which files you’re working on — so Claude Code follows the right conventions without you having to explain them.


The most powerful use case. The /create-theme skill walks Claude Code through a structured 5-step workflow:

  1. Research — reads all existing themes to understand what’s already there
  2. Differentiation — ensures the new theme is clearly distinct
  3. Proposal — presents a design concept (colors, layout, typography) and waits for your approval
  4. Implementation — generates the full theme: TSX components, CSS variables, theme.json
  5. Activation — the theme appears in Admin → Customizer immediately after npm run dev

How to use it:

In Claude Code, type:

/create-theme

Then describe what you want:

Create a dark, editorial theme inspired by longform magazines like The Atlantic.
Serif headings, wide article body, minimal sidebar.

Claude Code reads the theme specification docs, checks existing themes, proposes a design, and — after your approval — writes all the files.

themes/your-theme/
├── theme.json # Name, display name, font, `ai` field (Theme Provenance)
├── config.ts # Theme configuration
├── prompts/ # Theme Provenance (required)
│ ├── concept.md # Design concept & principles (English)
│ └── generation.md # Optional — the actual generation prompt
├── styles/theme.css # CSS variables
└── components/
├── layout/Layout.tsx
└── post/
├── PostCard.tsx
└── PostContent.tsx

The theme auto-registers via generate-theme-manifest on the next npm run dev. No manual registration needed.

Every Baan theme must bundle its design prompts — this is Baan’s Theme Provenance specification. theme.json records which AI agent produced the theme (ai.agent) and which skills were used (ai.skills), and prompts/concept.md documents the design intent in English so the theme can be forked, shared, or regenerated with a different agent. The /create-theme skill writes all of this automatically. See Themes → Creating → Theme Provenance for the specification.


You can also ask Claude Code to modify an existing theme. The .claude/rules/theme-system.md rule is loaded automatically when you’re working in themes/, so Claude Code knows:

  • Never modify built-in themes directly
  • Create a copy (fork) if you want to customize a built-in theme
  • How the CSS variable system works

Example:

Fork the `default` theme and make the accent color indigo,
increase the font size slightly, and remove the right sidebar.

With the Baan CLI configured, Claude Code can create, update, and publish articles directly from a conversation:

Terminal window
# Claude Code can run these on your behalf
baan posts list --json
baan posts create ./my-article.md
baan posts publish my-article-id
baan search "Next.js" --json
baan sync ./vault --dry-run

A typical AI-assisted publishing workflow:

You: "Write a post about deploying Next.js to Fly.io and publish it"
Claude Code:
1. baan categories list --json → checks existing categories
2. Writes the article as a .md file with proper frontmatter
3. baan posts create ./article.md → creates as draft
4. baan posts publish <id> → publishes

To set up the CLI for the first time:

Terminal window
baan init --url https://your-blog.com --key cms_live_xxxxxxxxxxxxxxxxxxxx

See External Editors & Baan CLI for CLI setup.


The /create-theme skill is just the beginning. Because CLAUDE.md and .claude/rules/ give Claude Code a complete understanding of Baan’s architecture, you can ask it to modify any part of the system — and it will follow the right patterns automatically.

New admin features

Add a "Scheduled Posts" feature to the admin panel.
Posts with a future `date` should be auto-published at that time.

Claude Code knows where admin routes live (app/baan-admin/[secretPath]/(authenticated)/), how settings are stored (via loadSettings()/saveSettings()), how the database schema works, and how to add i18n strings for the UI — without you explaining any of it.

New API endpoints

Add a /api/cms/v1/posts/:id/related endpoint that returns
the 5 most related posts based on shared tags and category.

The cms-api.md rule loads automatically when Claude Code works in app/api/cms/, ensuring the response format, auth (withApiAuth), and rate limiting follow the existing pattern.

New integrations

Add a Webmention receiver endpoint so other sites can send
webmentions when they link to my posts.

Admin UI modifications

Add a word count display to the post editor.
Show estimated reading time next to the word count.

The i18n.md rule ensures any new UI text goes through the translation system rather than being hardcoded — so it works in all 11 admin languages.

Storage and content pipeline changes

When a post is published, automatically generate an OGP image
using Sharp and save it to storage as images/ogp.png.

The settings-storage.md rule keeps Claude Code from reaching for fs directly — it uses the storage abstraction (storagePutFile) so the feature works on both local and cloud storage.

Security and access control

Add a read-only API endpoint that returns site analytics data,
protected by an API key.

Public-facing page customization

Add a /newsletter page that shows a subscription form
and the last 5 published posts as a preview.

Why This Works Without Constant Re-Explaining

Section titled “Why This Works Without Constant Re-Explaining”

The rules load automatically based on file paths:

RuleWhen it loadsWhat Claude Code knows
settings-storage.mdapp/baan-admin/**, lib/**Use loadSettings()/saveSettings(), never direct fs
theme-system.mdthemes/**, lib/theme*Auto-detection, no hardcoded theme names
security.mdAlwaysAuth requirements, Deny-by-Default, what never to commit
i18n.mdapp/baan-admin/**Use t() for all UI text, 11 admin languages
cms-api.mdapp/api/cms/**Response format {data, meta}, withApiAuth, rate limiting
database.mdlib/db/**getDB() singleton, SQL injection prevention, row mapping
api-performance.mdapp/**/api/**, lib/**Promise.all for parallel fetches, no await inside loops
error-handling.mdapp/**, lib/**No empty catch, consistent API error shape

In practice, this means you describe what you want. Claude Code figures out how — using Baan’s existing patterns rather than inventing its own.

You: Describe what you want to build or change
Claude Code: Reads relevant files, proposes an approach
You: Approve or redirect
Claude Code: Implements, then runs npm run build to verify
You: Test it in the browser

For larger changes, Claude Code will break work into steps and check in with you before each one — especially for anything touching auth, the database schema, or the storage layer.


Baan has a test suite for unit, integration, and end-to-end tests. After making code changes with Claude Code, verify nothing is broken:

Terminal window
npm run build # Must pass — validates compilation and theme registry
npm test # Unit tests (Vitest)
npm run test:security # Security-specific tests
npm run test:e2e # End-to-end tests (Playwright)

Claude Code knows to run npm run build as a verification step after significant changes — this is specified in CLAUDE.md.

CommandWhat it tests
npm testBusiness logic, API handlers, security utilities, DB operations, Knowledge Graph
npm run test:securityAuth flows, rate limiting, token handling, cookie security
npm run test:e2eFull browser flows — login, post creation, publishing, settings

Tests run against a separate data/test.db on port 3001, isolated from your development database. Your data/app.db is never touched by tests.


SkillHow to invokeWhat it does
/create-themeType in Claude CodeFull theme creation workflow with proposal + approval step. Writes theme.json ai field and prompts/concept.md for Theme Provenance
/import-theme-skillsType in Claude CodeCopy custom Claude Code skills bundled inside a theme (themes/<name>/prompts/skills/) into your local .claude/skills/ directory
/build-strategyType in Claude CodeGuide for switching between ISR, SSG, and SSR
/content-managementType in Claude CodeContent pipeline, taxonomy, static pages, search index
/release-checkType in Claude CodePre-release checklist — README, env vars, source code review