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:

Template

Define your branch naming pattern using placeholders:

template: '{{type}}/{{ticket}}-{{desc}}'

Available placeholders:

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:

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:

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+$/
  }],
}