Configuration
Customize Branchwright to match your team's workflow and naming conventions.
Configuration File
Create branchwright.config.ts in your project root:
import { defineConfig } from '@branchwright/cli';
export default defineConfig({
// Your configuration here
});
Configuration Options
Branch Types
Define the types of branches your team uses:
branchTypes: [
{ name: 'feat', label: 'Feature' },
{ name: 'fix', label: 'Bug Fix' },
{ name: 'chore', label: 'Chore' },
{ name: 'docs', label: 'Documentation' },
{ name: 'refactor', label: 'Refactor' },
{ name: 'test', label: 'Testing' },
]
Options:
name- Short identifier used in branch nameslabel- User-friendly display name in prompts
Template
Define your branch naming pattern using placeholders:
template: '{{type}}/{{ticket}}-{{desc}}'
Available placeholders:
{{type}}- Branch type (feat, fix, etc.){{ticket}}- Ticket/issue ID{{desc}}- Description
Common patterns:
// Type and description only
'{{type}}/{{desc}}'
// Result: feat/user-authentication
// With ticket prefix
'{{type}}/{{ticket}}-{{desc}}'
// Result: feat/PROJ-123-user-authentication
// Ticket first
'{{ticket}}/{{type}}-{{desc}}'
// Result: PROJ-123/feat-user-authentication
// Simple flat structure
'{{type}}-{{desc}}'
// Result: feat-user-authentication
Description Settings
maxDescriptionLength: 50,
descriptionStyle: 'kebab-case'
Description styles:
kebab-case- user-authentication (default)snake_case- user_authenticationcamelCase- userAuthenticationPascalCase- UserAuthentication
Ignored Branches
Branches that should be excluded from validation:
ignoredBranches: ['main', 'master', 'dev', 'staging', 'production']
Extra Questions
Enable optional prompts during branch creation:
extraQuestions: {
baseBranch: false, // Ask which branch to base from
checkout: false, // Ask whether to switch to new branch
pushToRemote: false, // Ask whether to push to remote
}
All default to false for a streamlined workflow. When disabled:
- baseBranch: Uses current branch
- checkout: Automatically switches to new branch
- pushToRemote: Does not push (you push manually)
Custom Prompts
Override default prompt text:
questions: {
branchType: 'What type of work is this?',
ticketId: 'Enter ticket number (optional):',
description: 'Brief description:',
baseBranch: 'Create from which branch?',
checkout: 'Switch to this branch now?',
pushToRemote: 'Push to origin?',
}
Rules Configuration
Ticket ID Rules
Control ticket ID requirements and format:
rules: {
// No validation
ticketId: 'off',
// Optional with prefix
ticketId: ['optional', { prefix: 'PROJ-' }],
// Required with prefix
ticketId: ['required', { prefix: 'TEAM-' }],
// Required with pattern
ticketId: ['required', {
pattern: /^[A-Z]+-\d+$/,
message: 'Ticket must be format: ABC-123'
}],
}
Custom Rules
Define your own validation rules:
import { defineRule, createRegistry, coreRuleRegistry } from '@branchwright/cli';
const noWipRule = defineRule(
{
id: 'no-wip',
meta: {
title: 'Disallow WIP branches',
description: 'Prevents work-in-progress markers',
},
defaultSeverity: 'required',
},
(context) => {
if (context.branchName.includes('wip')) {
return {
message: 'Remove "wip" from branch name',
suggestions: [context.branchName.replace('wip', '')]
};
}
return null;
}
);
export default defineConfig({
rules: {
'no-wip': 'required',
},
});
Rule Plugins
Load rules from external modules:
export default defineConfig({
plugins: [
'./config/custom-rules.ts', // Local file
'@company/branchwright-rules', // npm package
],
rules: {
'custom-rule': 'required',
'company/naming': ['optional', { strict: true }],
},
});
Rule Presets
Use predefined rule configurations:
export default defineConfig({
presets: [
'recommended', // Built-in preset
'@company/strict', // Package preset
],
rules: {
// Override preset defaults
ticketId: 'required',
},
});
Complete Example
import { defineConfig } from '@branchwright/cli';
export default defineConfig({
// Branch types
branchTypes: [
{ name: 'feat', label: '✨ Feature' },
{ name: 'fix', label: '🐛 Bug Fix' },
{ name: 'chore', label: '🔧 Chore' },
{ name: 'docs', label: '📚 Documentation' },
{ name: 'refactor', label: '♻️ Refactor' },
],
// Branch name format
template: '{{type}}/{{ticket}}-{{desc}}',
maxDescriptionLength: 50,
descriptionStyle: 'kebab-case',
// Validation rules
rules: {
ticketId: ['optional', { prefix: 'PROJ-' }],
},
// Protected branches
ignoredBranches: ['main', 'master', 'dev', 'staging'],
// Streamlined workflow (minimal prompts)
extraQuestions: {
baseBranch: false,
checkout: false,
pushToRemote: false,
},
// Custom prompt text
questions: {
branchType: 'Select branch type:',
description: 'Describe your changes:',
},
});
Team Configurations
Monorepo Setup
// Prefix with package name
template: '{{package}}/{{type}}/{{desc}}'
Jira Integration
template: '{{type}}/{{ticket}}-{{desc}}',
rules: {
ticketId: ['required', {
prefix: 'PROJ-',
pattern: /^PROJ-\d+$/
}],
}
Linear Integration
template: '{{type}}/{{ticket}}-{{desc}}',
rules: {
ticketId: ['optional', {
pattern: /^[A-Z]+-\d+$/
}],
}