---
title: 'How to Customize BMad'
description: Customize agents and workflows while preserving update compatibility
sidebar:
  order: 8
---

Tailor agent personas, inject domain context, add capabilities, and configure workflow behavior -- all without modifying installed files. Your customizations survive every update.

## When to Use This

- You want to change an agent's personality or communication style
- You need to give an agent persistent facts to recall (e.g. "our org is AWS-only")
- You want to add procedural startup steps the agent must run every session
- You want to add custom menu items that trigger your own skills or prompts
- Your team needs shared customizations committed to git, with personal preferences layered on top

:::note[Prerequisites]

- BMad installed in your project (see [How to Install BMad](./install-bmad.md))
- Python 3.11+ on your PATH (for the resolver script -- uses stdlib `tomllib`, no `pip install`, no `uv`, no virtualenv)
- A text editor for TOML files
:::

## How It Works

Every customizable skill ships a `customize.toml` file with its defaults. This file defines the skill's complete customization surface -- read it to see what's customizable. You never edit this file. Instead, you create sparse override files containing only the fields you want to change.

### Three-Layer Override Model

```text
Priority 1 (wins): _bmad/custom/{skill-name}.user.toml  (personal, gitignored)
Priority 2:        _bmad/custom/{skill-name}.toml        (team/org, committed)
Priority 3 (last): skill's own customize.toml                    (defaults)
```

The `_bmad/custom/` folder starts empty. Files only appear when someone actively customizes.

### Merge Rules (by shape, not by field name)

The resolver applies four structural rules. Field names are never special-cased — behavior is determined purely by the value's shape:

| Shape | Rule |
|---|---|
| Scalar (string, int, bool, float) | Override wins |
| Table | Deep merge (recursively apply these rules) |
| Array of tables where every item has a `code` or `id` field | Merge by that key — matching keys **replace in place**, new keys **append** |
| Any other array (scalars, mixed, tables without `code`/`id`) | **Append** — base items first, then team items, then user items |

**No removal mechanism.** Overrides cannot delete base items. If you need to suppress a default menu item, override it by `code` with a no-op description or prompt. If you need to restructure an array more deeply, fork the skill.

#### The `code` / `id` convention

BMad uses `code` (short identifier like `"BP"` or `"R1"`) and `id` (longer stable identifier) as merge keys on arrays of tables. If you author a custom array-of-tables that should be replaceable-by-key rather than append-only, give every item a `code` or `id` field.

### Some agent fields are read-only

`agent.name` and `agent.title` live in `customize.toml` as source-of-truth metadata, but the agent's SKILL.md doesn't read them at runtime — they're hardcoded identity. Putting `name = "Bob"` in an override file has no effect. If you genuinely need a different-named agent, copy the skill folder, rename it, and ship it as a custom skill.

## Steps

### 1. Find the Skill's Customization Surface

Look at the skill's `customize.toml` in its installed directory. For example, the PM agent:

```text
.claude/skills/bmad-agent-pm/customize.toml
```

(Path varies by IDE -- Cursor uses `.cursor/skills/`, Cline uses `.cline/skills/`, and so on.)

This file is the canonical schema. Every field you see is customizable (excluding the read-only identity fields noted above).

### 2. Create Your Override File

Create the `_bmad/custom/` directory in your project root if it doesn't exist. Then create a file named after the skill:

```text
_bmad/custom/
  bmad-agent-pm.toml        # team overrides (committed to git)
  bmad-agent-pm.user.toml   # personal preferences (gitignored)
```

:::caution[Do NOT copy the whole `customize.toml`]
Override files are **sparse**. Include only the fields you're changing — nothing else. Every field you omit is inherited automatically from the layer below (team from defaults, user from team-or-defaults).

Copying the full `customize.toml` into an override is actively harmful: the next update ships new defaults, but your override file locks in the old values. You'll silently drift out of sync with every release.
:::

**Example — changing the icon and adding one principle**:

```toml
# _bmad/custom/bmad-agent-pm.toml
# Just the fields I'm changing. Everything else inherits.

[agent]
icon = "🏥"
principles = [
  "Ship nothing that can't pass an FDA audit.",
]
```

This appends the new principle to the defaults (leaving the shipped principles intact) and replaces the icon. Every other field stays as shipped.

### 3. Customize What You Need

All examples below assume BMad's flat agent schema. Fields live directly under `[agent]` — no nested `metadata` or `persona` sub-tables.

#### Scalars (icon, role, identity, communication_style)

Scalar overrides simply win. You only need to set the fields you're changing:

```toml
# _bmad/custom/bmad-agent-pm.toml

[agent]
icon = "🏥"
role = "Drives product discovery for a regulated healthcare domain."
communication_style = "Precise, regulatory-aware, asks compliance-shaped questions early."
```

#### Persistent Facts, Principles, Activation Hooks (append arrays)

All four arrays below are append-only. Team items run after defaults, user items run last.

```toml
[agent]
# Static facts the agent keeps in mind the whole session — org rules, domain
# constants, user preferences. Distinct from the runtime memory sidecar.
#
# Each entry is either a literal sentence, or a `file:` reference whose
# contents are loaded as facts (glob patterns supported).
persistent_facts = [
  "Our org is AWS-only -- do not propose GCP or Azure.",
  "All PRDs require legal sign-off before engineering kickoff.",
  "Target users are clinicians, not patients -- frame examples accordingly.",
  "file:{project-root}/docs/compliance/hipaa-overview.md",
  "file:{project-root}/_bmad/custom/company-glossary.md",
]

# Adds to the agent's value system
principles = [
  "Ship nothing that can't pass an FDA audit.",
  "User value first, compliance always.",
]

# Runs BEFORE the standard activation (persona, persistent_facts, config, greet).
# Use for pre-flight loads, compliance checks, anything that needs to be in
# context before the agent introduces itself.
activation_steps_prepend = [
  "Scan {project-root}/docs/compliance/ and load any HIPAA-related documents as context.",
]

# Runs AFTER greet, BEFORE the menu. Use for context-heavy setup that should
# happen once the user has been acknowledged.
activation_steps_append = [
  "Read {project-root}/_bmad/custom/company-glossary.md if it exists.",
]
```

**Why two hooks?** Prepend runs before greeting so the agent can load context it needs to personalize the greeting itself. Append runs after greeting so the user isn't staring at a blank terminal while heavy scans complete.

#### Menu Customization (merge by `code`)

The menu is an array of tables. Each item has a `code` field (BMad convention), so the resolver merges by code: matching codes replace in place, new codes append.

TOML array-of-tables syntax uses `[[agent.menu]]` for each item:

```toml
# Replace the existing CE item with a custom skill
[[agent.menu]]
code = "CE"
description = "Create Epics using our delivery framework"
skill = "custom-create-epics"

# Add a new item (code RC doesn't exist in defaults)
[[agent.menu]]
code = "RC"
description = "Run compliance pre-check"
prompt = """
Read {project-root}/_bmad/custom/compliance-checklist.md
and scan all documents in {planning_artifacts} against it.
Report any gaps and cite the relevant regulatory section.
"""
```

Each menu item has exactly one of `skill` (invokes a registered skill) or `prompt` (executes the text directly). Items not listed in your override keep their defaults.

#### Referencing Files

When a field's text needs to point at a file (in `persistent_facts`, `activation_steps_prepend`/`activation_steps_append`, or a menu item's `prompt`), use a full path rooted at `{project-root}`. Even if the file sits next to your override in `_bmad/custom/`, spell out the full path: `{project-root}/_bmad/custom/info.md`. The agent resolves `{project-root}` at runtime.

### 4. Personal vs Team

**Team file** (`bmad-agent-pm.toml`): Committed to git. Shared across the org. Use for compliance rules, company persona, custom capabilities.

**Personal file** (`bmad-agent-pm.user.toml`): Gitignored automatically. Use for tone adjustments, personal workflow preferences, and private facts the agent should keep in mind.

```toml
# _bmad/custom/bmad-agent-pm.user.toml

[agent]
persistent_facts = [
  "Always include a rough complexity estimate (low/medium/high) when presenting options.",
]
```

## How Resolution Works

On activation, the agent's SKILL.md runs a shared Python script that does the three-layer merge and returns the resolved block as JSON. The script uses the Python standard library's `tomllib` module (no external dependencies), so plain `python3` is enough:

```bash
python3 {project-root}/_bmad/scripts/resolve_customization.py \
  --skill {skill-root} \
  --key agent
```

**Requirements**: Python 3.11+ (earlier versions don't include `tomllib`). No `pip install`, no `uv`, no virtualenv. macOS 13+, Ubuntu 22.04+, Debian 12+, and Fedora 37+ all ship 3.11 or newer.

`--skill` points at the skill's installed directory (where `customize.toml` lives). The skill name is derived from the directory's basename, and the script looks up `_bmad/custom/{skill-name}.toml` and `{skill-name}.user.toml` automatically.

Useful invocations:

```bash
# Resolve the full agent block
python3 {project-root}/_bmad/scripts/resolve_customization.py \
  --skill /abs/path/to/bmad-agent-pm \
  --key agent

# Resolve a single field
python3 {project-root}/_bmad/scripts/resolve_customization.py \
  --skill /abs/path/to/bmad-agent-pm \
  --key agent.icon

# Full dump
python3 {project-root}/_bmad/scripts/resolve_customization.py \
  --skill /abs/path/to/bmad-agent-pm
```

Output is always JSON. If the script is unavailable on a given platform, the SKILL.md tells the agent to read the three TOML files directly and apply the same merge rules.

## Workflow Customization

Workflows (skills that drive multi-step processes like `bmad-product-brief`) share the same override mechanism as agents. Their customizable surface lives under `[workflow]` instead of `[agent]`, keeping the two namespaces cleanly separated:

```toml
# _bmad/custom/bmad-product-brief.toml

[workflow]
# Same prepend/append semantics as agents — runs before and after the workflow's
# own activation steps. Overrides append to defaults.
activation_steps_prepend = [
  "Load {project-root}/docs/product/north-star-principles.md as context.",
]

activation_steps_append = []

# Same literal-or-file: semantics as the agent variant. Loaded as foundational
# context for the duration of the workflow run.
persistent_facts = [
  "All briefs must include an explicit regulatory-risk section.",
  "file:{project-root}/docs/compliance/product-brief-checklist.md",
]

# Scalar: runs once the workflow finishes its main output. Override wins.
on_complete = "Summarize the brief in three bullets and offer to email it via the gws-gmail-send skill."
```

The same field conventions cross the agent/workflow boundary: `activation_steps_prepend`/`activation_steps_append`, `persistent_facts` (with `file:` refs), menu-style `[[…]]` tables with `code`/`id` for keyed merge. The resolver applies the same four structural rules regardless of the top-level key. SKILL.md references follow the namespace: `{workflow.activation_steps_prepend}`, `{workflow.persistent_facts}`, `{workflow.on_complete}`. Any additional fields a workflow exposes (output paths, toggles, review settings, stage flags) follow the same merge rules based on their shape. Read the workflow's `customize.toml` to see what it makes customizable.

## Troubleshooting

**Customization not appearing?**

- Verify your file is in `_bmad/custom/` with the correct skill name
- Check TOML syntax: strings must be quoted, table headers use `[section]`, array-of-tables use `[[section]]`, and any scalar or array keys for a table must appear *before* any of that table's `[[subtables]]` in the file
- For agents, customization lives under `[agent]` -- fields written below that header belong to `agent` until another table header begins
- Remember `agent.name` and `agent.title` are read-only; overrides there have no effect

**Updates broke my customization?**

- Did you copy the full `customize.toml` into your override file? **Don't.** Override files should contain only the fields you're changing. A full copy locks in old defaults and silently drifts every release. Trim your override back to just the deltas.

**Need to see what's customizable?**

- Read the skill's `customize.toml` -- every field there is customizable (except `name` and `title`)

**Need to reset?**

- Delete your override file from `_bmad/custom/` -- the skill falls back to its built-in defaults
