Node.js/JavaScript API for using bmad-method programmatically in your own scripts and applications.
The bmad-method package exports several modules that can be imported and used programmatically for:
Main installation and management API exported from tools/installer/lib/installer.js.
const installer = require('bmad-method/tools/installer/lib/installer');Install BMad Method to a project directory.
/**
* Install BMad Method with specified configuration
* @param {InstallConfig} config - Installation configuration
* @returns {Promise<void>}
*/
await installer.install(config);
interface InstallConfig {
installType: 'full' | 'expansion-only';
directory: string; // Installation directory (absolute or relative)
ides?: string[]; // IDE IDs to configure (optional)
expansionPacks?: string[]; // Expansion pack IDs to install (optional)
prdSharded?: boolean; // Enable PRD sharding (default: true)
architectureSharded?: boolean; // Enable architecture sharding (default: true)
includeWebBundles?: boolean; // Include web bundles (default: false)
webBundlesDirectory?: string; // Web bundles directory (default: 'web-bundles')
}Example:
const installer = require('bmad-method/tools/installer/lib/installer');
await installer.install({
installType: 'full',
directory: '/path/to/project',
ides: ['claude-code', 'cursor'],
expansionPacks: ['bmad-godot-game-dev'],
prdSharded: true,
architectureSharded: true,
includeWebBundles: true,
webBundlesDirectory: './web-bundles'
});Update an existing BMad installation.
/**
* Update existing BMad installation
* @returns {Promise<void>}
*/
await installer.update();Example:
await installer.update();Check the installation state of a directory.
/**
* Detect installation state
* @param {string} installDir - Directory to check
* @returns {Promise<InstallationState>}
*/
await installer.detectInstallationState(dirPath);
interface InstallationState {
type: 'clean' | 'v4_existing' | 'v3_existing' | 'unknown_existing';
hasV4Manifest: boolean;
hasV3Structure: boolean;
hasBmadCore: boolean;
hasOtherFiles: boolean;
manifest: object | null;
expansionPacks: Record<string, ExpansionPackInfo>;
}Example:
const state = await installer.detectInstallationState('/path/to/project');
console.log('Installation type:', state.type);
if (state.manifest) {
console.log('Installed version:', state.manifest.coreVersion);
}Display available expansion packs.
/**
* List available expansion packs
* @returns {Promise<void>} - Prints to console
*/
await installer.listExpansionPacks();Get array of available expansion packs.
/**
* Get available expansion packs
* @returns {Promise<ExpansionPack[]>}
*/
await installer.getAvailableExpansionPacks();
interface ExpansionPack {
id: string;
name: string;
version: string;
description: string;
author?: string;
}Get array of available agent teams.
/**
* Get available teams
* @returns {Promise<string[]>}
*/
await installer.getAvailableTeams();Display installation status.
/**
* Show installation status
* @returns {Promise<void>} - Prints to console
*/
await installer.showStatus();Get the BMad core version.
/**
* Get BMad core version
* @returns {Promise<string>}
*/
await installer.getCoreVersion();Flatten a codebase to XML format for brownfield development.
/**
* Flatten codebase to XML
* @param {FlattenOptions} options - Flatten options
* @returns {Promise<void>}
*/
await installer.flatten(options);
interface FlattenOptions {
input?: string; // Input directory (default: current directory)
output?: string; // Output file path (default: 'flattened-codebase.xml')
}Example:
await installer.flatten({
input: './src',
output: 'src-flattened.xml'
});Build web bundles for agents and teams. Exported from tools/builders/web-builder.js.
const WebBuilder = require('bmad-method/tools/builders/web-builder');/**
* Create WebBuilder instance
* @param {WebBuilderOptions} options
*/
const builder = new WebBuilder(options);
interface WebBuilderOptions {
rootDir: string; // Root directory (default: process.cwd())
}Build web bundles for all agents.
/**
* Build agent bundles
* @returns {Promise<void>}
*/
await builder.buildAgents();Example:
const WebBuilder = require('bmad-method/tools/builders/web-builder');
const builder = new WebBuilder({ rootDir: process.cwd() });
await builder.buildAgents();
// Output: dist/agents/*.txtBuild web bundles for all teams.
/**
* Build team bundles
* @returns {Promise<void>}
*/
await builder.buildTeams();Build web bundles for all expansion packs.
/**
* Build all expansion pack bundles
* @param {BuildOptions} options
* @returns {Promise<void>}
*/
await builder.buildAllExpansionPacks(options);
interface BuildOptions {
clean?: boolean; // Clean output directory first (default: true)
}Build web bundle for a specific expansion pack.
/**
* Build specific expansion pack bundle
* @param {string} packName - Expansion pack ID
* @param {BuildOptions} options
* @returns {Promise<void>}
*/
await builder.buildExpansionPack(packName, options);Example:
await builder.buildExpansionPack('bmad-creative-writing', { clean: true });
// Output: dist/expansion-packs/bmad-creative-writing/*.txtList available expansion packs.
/**
* List expansion packs
* @returns {Promise<string[]>}
*/
const packs = await builder.listExpansionPacks();Clean output directories before building.
/**
* Clean output directories
* @returns {Promise<void>}
*/
await builder.cleanOutputDirs();Resolve agent and team dependencies. Exported from tools/lib/dependency-resolver.js.
const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');/**
* Create DependencyResolver instance
* @param {string} projectRoot - Project root directory
*/
const resolver = new DependencyResolver(projectRoot);Resolve all dependencies for an agent.
/**
* Resolve agent dependencies
* @param {string} agentId - Agent ID (e.g., 'dev', 'pm', 'qa')
* @returns {Promise<ResolvedDependencies>}
*/
const deps = await resolver.resolveAgentDependencies(agentId);
interface ResolvedDependencies {
tasks: string[]; // Task file paths
templates: string[]; // Template file paths
checklists: string[]; // Checklist file paths
data: string[]; // Data file paths
agents: string[]; // Referenced agent file paths
}Example:
const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');
const resolver = new DependencyResolver('/path/to/project');
const devDeps = await resolver.resolveAgentDependencies('dev');
console.log('Dev agent tasks:', devDeps.tasks);
console.log('Dev agent templates:', devDeps.templates);Resolve all dependencies for a team.
/**
* Resolve team dependencies
* @param {string} teamId - Team ID (e.g., 'team-fullstack')
* @returns {Promise<TeamDependencies>}
*/
const teamDeps = await resolver.resolveTeamDependencies(teamId);
interface TeamDependencies {
agents: string[]; // Agent IDs in team
workflows: string[]; // Workflow file paths
allDeps: ResolvedDependencies; // Combined dependencies from all agents
}List all available agents.
/**
* List all agents
* @returns {Promise<string[]>} - Agent IDs
*/
const agents = await resolver.listAgents();Example:
const agents = await resolver.listAgents();
// Returns: ['bmad-orchestrator', 'analyst', 'pm', 'architect', 'dev', 'qa', 'sm', 'po', 'ux-expert']List all available teams.
/**
* List all teams
* @returns {Promise<string[]>} - Team IDs
*/
const teams = await resolver.listTeams();Example:
const teams = await resolver.listTeams();
// Returns: ['team-fullstack', 'team-ide-minimal', 'team-no-ui', 'team-all']Upgrade V3 projects to V4 format. Exported from tools/upgraders/v3-to-v4-upgrader.js.
const V3ToV4Upgrader = require('bmad-method/tools/upgraders/v3-to-v4-upgrader');/**
* Create V3ToV4Upgrader instance
*/
const upgrader = new V3ToV4Upgrader();Upgrade a V3 project to V4.
/**
* Upgrade V3 project to V4
* @param {UpgradeOptions} options
* @returns {Promise<void>}
*/
await upgrader.upgrade(options);
interface UpgradeOptions {
projectPath?: string; // Path to V3 project (default: current directory)
dryRun?: boolean; // Preview changes without applying (default: false)
backup?: boolean; // Create backup before upgrade (default: true)
}Example:
const V3ToV4Upgrader = require('bmad-method/tools/upgraders/v3-to-v4-upgrader');
const upgrader = new V3ToV4Upgrader();
// Preview upgrade
await upgrader.upgrade({
projectPath: '/path/to/v3/project',
dryRun: true
});
// Apply upgrade
await upgrader.upgrade({
projectPath: '/path/to/v3/project',
dryRun: false,
backup: true
});Manage package versions. Exported from tools/version-bump.js.
const { bumpVersion, getCurrentVersion } = require('bmad-method/tools/version-bump');Get current package version.
/**
* Get current version
* @returns {Promise<string>}
*/
const version = await getCurrentVersion();Bump package version.
/**
* Bump package version
* @param {string} type - Version bump type ('major' | 'minor' | 'patch')
* @returns {Promise<string>} - New version
*/
const newVersion = await bumpVersion(type);Example:
const { bumpVersion, getCurrentVersion } = require('bmad-method/tools/version-bump');
const currentVersion = await getCurrentVersion();
console.log('Current version:', currentVersion); // 4.44.3
const newVersion = await bumpVersion('patch');
console.log('New version:', newVersion); // 4.44.4Parse YAML from agent definition files. Exported from tools/lib/yaml-utils.js.
const { extractYamlFromAgent } = require('bmad-method/tools/lib/yaml-utils');Extract YAML configuration from agent markdown file.
/**
* Extract YAML from agent file
* @param {string} filePath - Path to agent .md file
* @returns {Promise<AgentConfig>}
*/
const config = await extractYamlFromAgent(filePath);
interface AgentConfig {
agent: {
id: string;
name: string;
title: string;
icon: string;
whenToUse: string;
};
persona: {
role: string;
style: string;
identity: string;
focus: string;
};
commands: Array<Record<string, string>>;
dependencies?: {
tasks?: string[];
templates?: string[];
checklists?: string[];
data?: string[];
agents?: string[];
};
'activation-instructions'?: string[];
}Example:
const { extractYamlFromAgent } = require('bmad-method/tools/lib/yaml-utils');
const config = await extractYamlFromAgent('.bmad-core/agents/dev.md');
console.log('Agent ID:', config.agent.id);
console.log('Agent name:', config.agent.name);
console.log('Commands:', config.commands);
console.log('Dependencies:', config.dependencies);const installer = require('bmad-method/tools/installer/lib/installer');
const WebBuilder = require('bmad-method/tools/builders/web-builder');
const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');
async function setupBmadProject() {
// 1. Install BMad to a project
await installer.install({
installType: 'full',
directory: './my-project',
ides: ['claude-code', 'cursor'],
expansionPacks: ['bmad-godot-game-dev'],
prdSharded: true,
architectureSharded: true
});
// 2. Check installation status
const state = await installer.detectInstallationState('./my-project');
console.log('Installation state:', state.type);
// 3. List available agents
const resolver = new DependencyResolver('./my-project');
const agents = await resolver.listAgents();
console.log('Available agents:', agents);
// 4. Resolve dependencies for dev agent
const devDeps = await resolver.resolveAgentDependencies('dev');
console.log('Dev agent dependencies:', devDeps);
// 5. Build web bundles
const builder = new WebBuilder({ rootDir: './my-project' });
await builder.buildAgents();
await builder.buildTeams();
console.log('Web bundles built successfully');
}
setupBmadProject().catch(console.error);All asynchronous methods throw errors that should be caught and handled.
interface BMadError extends Error {
code: string;
message: string;
details?: string;
}
// Common error codes
type ErrorCode =
| 'EACCES' // Permission denied
| 'ENOENT' // File/directory not found
| 'EEXIST' // File/directory already exists
| 'INVALID_CONFIG' // Invalid configuration
| 'INVALID_IDE' // Unknown IDE
| 'INVALID_PACK' // Unknown expansion pack
| 'BUILD_FAILED' // Build process failed
| 'RESOLVE_FAILED' // Dependency resolution failed
| 'UPGRADE_FAILED' // Upgrade process failed
| 'VERSION_ERROR' // Version management error
| 'YAML_PARSE_ERROR'; // YAML parsing failedtry {
await installer.install(config);
} catch (error) {
console.error('Installation failed:', error.message);
// Handle specific error cases
switch (error.code) {
case 'EACCES':
console.error('Permission denied. Try a different directory or use sudo.');
break;
case 'ENOENT':
console.error('Directory not found. Check the path:', config.directory);
break;
case 'EEXIST':
console.error('Installation already exists. Use update command instead.');
break;
case 'INVALID_CONFIG':
console.error('Invalid configuration:', error.details);
break;
case 'INVALID_IDE':
console.error('Unknown IDE. Valid options:', ['cursor', 'claude-code', 'windsurf']);
break;
case 'INVALID_PACK':
console.error('Unknown expansion pack. Use list:expansions to see available packs.');
const packs = await installer.getAvailableExpansionPacks();
console.log('Available:', packs.map(p => p.id));
break;
default:
console.error('Unexpected error:', error);
}
}const WebBuilder = require('bmad-method/tools/builders/web-builder');
const builder = new WebBuilder({ rootDir: process.cwd() });
try {
await builder.buildAgents();
} catch (error) {
if (error.code === 'BUILD_FAILED') {
console.error('Build failed:', error.details);
console.error('Check that bmad-core is properly installed');
} else {
console.error('Unexpected build error:', error);
}
}const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');
const resolver = new DependencyResolver('/path/to/project');
try {
const deps = await resolver.resolveAgentDependencies('invalid-agent');
} catch (error) {
if (error.code === 'ENOENT') {
console.error('Agent not found. Available agents:');
const agents = await resolver.listAgents();
console.log(agents.join(', '));
} else if (error.code === 'RESOLVE_FAILED') {
console.error('Failed to resolve dependencies:', error.details);
}
}While bmad-method is written in JavaScript, you can use it in TypeScript projects by creating type declaration files based on the interfaces documented above, or by using @ts-check comments with JSDoc annotations.
interface ProgrammaticAPIBestPractices {
installation: {
validateDirectory: 'Always check directory exists before installing';
handleErrors: 'Wrap all async calls in try-catch';
checkState: 'Use detectInstallationState before operations';
};
building: {
cleanFirst: 'Clean output directories before building';
sequential: 'Build agents, then teams, then expansion packs';
verify: 'Check output directory after build completes';
};
dependencies: {
resolve: 'Always resolve dependencies before bundling';
cache: 'Cache resolver instance for repeated operations';
validate: 'Validate all dependencies exist before building';
};
versioning: {
check: 'Check current version before bumping';
backup: 'Always backup before version changes';
validate: 'Validate new version format';
};
}