The Angular CLI provides deep integration with Angular Schematics for code generation, project modification, and automated development tasks. This system enables both built-in Angular schematics and custom third-party schematics with consistent APIs and configuration management.
Abstract base class for commands that execute schematics with built-in collection management and option parsing.
/**
* Base class for commands that run schematics
*/
abstract class SchematicsCommandModule extends CommandModule {
/** Default schematic collection name */
protected readonly defaultCollectionName: string;
/**
* Run a schematic with the specified options
* @param options - Schematic execution options
* @returns Promise that resolves when schematic completes
*/
protected runSchematic(options: {
collection: string;
schematic: string;
options: Record<string, any>;
dryRun?: boolean;
force?: boolean;
allowPrivate?: boolean;
}): Promise<void>;
/**
* Get available schematics from a collection
* @param collection - Collection name to query
* @returns Array of available schematic names
*/
protected getAvailableSchematics(collection: string): Promise<string[]>;
/**
* Get schematic options schema
* @param collection - Collection name
* @param schematic - Schematic name
* @returns JSON schema for schematic options
*/
protected getSchematicSchema(
collection: string,
schematic: string
): Promise<JsonSchema>;
}Usage Examples:
// Custom command extending SchematicsCommandModule
class CustomGenerateCommand extends SchematicsCommandModule {
protected readonly defaultCollectionName = '@schematics/angular';
async run(options: any) {
// Run component schematic
await this.runSchematic({
collection: '@schematics/angular',
schematic: 'component',
options: {
name: 'my-component',
skipTests: true,
style: 'scss'
}
});
}
}Functions for managing schematic defaults and collection settings.
/**
* Get default options for a schematic from workspace configuration
* @param collection - Schematic collection name
* @param schematic - Schematic name within collection
* @param project - Project name for project-specific defaults
* @returns Default options object
*/
function getSchematicDefaults(
collection: string,
schematic: string,
project?: string
): Record<string, any>;
/**
* Set default options for a schematic in workspace configuration
* @param collection - Schematic collection name
* @param schematic - Schematic name within collection
* @param options - Default options to set
* @param project - Project name for project-specific defaults
* @returns Promise that resolves when defaults are saved
*/
function setSchematicDefaults(
collection: string,
schematic: string,
options: Record<string, any>,
project?: string
): Promise<void>;
/**
* Get configured default collection for workspace
* @param workspace - Angular workspace instance
* @returns Default collection name
*/
function getDefaultCollection(workspace?: AngularWorkspace): string;Usage Examples:
import {
getSchematicDefaults,
setSchematicDefaults,
getDefaultCollection
} from "@angular/cli";
// Get current component defaults
const componentDefaults = getSchematicDefaults(
'@schematics/angular',
'component'
);
console.log('Component defaults:', componentDefaults);
// Set new component defaults
await setSchematicDefaults(
'@schematics/angular',
'component',
{
skipTests: true,
style: 'scss',
changeDetection: 'OnPush'
}
);
// Get default collection
const defaultCollection = getDefaultCollection();
console.log(`Default collection: ${defaultCollection}`);Functions for discovering available schematics and validating their configurations.
/**
* List all available schematics in a collection
* @param collection - Collection name to inspect
* @returns Promise resolving to array of schematic descriptors
*/
function listSchematics(collection: string): Promise<SchematicDescriptor[]>;
/**
* Validate schematic options against schema
* @param collection - Collection name
* @param schematic - Schematic name
* @param options - Options to validate
* @returns Validation result with errors if any
*/
function validateSchematicOptions(
collection: string,
schematic: string,
options: Record<string, any>
): Promise<SchematicValidationResult>;
/**
* Check if a collection is installed and available
* @param collection - Collection name to check
* @returns Promise resolving to availability status
*/
function isCollectionAvailable(collection: string): Promise<boolean>;Usage Examples:
import {
listSchematics,
validateSchematicOptions,
isCollectionAvailable
} from "@angular/cli";
// List available schematics
const schematics = await listSchematics('@schematics/angular');
console.log('Available schematics:');
schematics.forEach(s => {
console.log(`- ${s.name}: ${s.description}`);
});
// Validate options before running
const validation = await validateSchematicOptions(
'@schematics/angular',
'component',
{
name: 'MyComponent',
style: 'scss',
skipTests: true
}
);
if (!validation.isValid) {
console.error('Validation errors:', validation.errors);
}
// Check collection availability
const isAvailable = await isCollectionAvailable('@angular/material');
if (!isAvailable) {
console.log('Angular Material schematics not installed');
}The Angular CLI includes comprehensive built-in schematics for common development tasks.
// Application schematic
interface ApplicationSchematicOptions {
name: string;
version?: string;
routing?: boolean;
style?: 'css' | 'scss' | 'sass' | 'less';
inlineStyle?: boolean;
inlineTemplate?: boolean;
skipTests?: boolean;
skipGit?: boolean;
skipInstall?: boolean;
packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';
directory?: string;
prefix?: string;
}
// Library schematic
interface LibrarySchematicOptions {
name: string;
prefix?: string;
skipPackageJson?: boolean;
skipTsConfig?: boolean;
skipInstall?: boolean;
}// Component schematic
interface ComponentSchematicOptions {
name: string;
path?: string;
project?: string;
style?: 'css' | 'scss' | 'sass' | 'less' | 'none';
skipTests?: boolean;
inlineStyle?: boolean;
inlineTemplate?: boolean;
standalone?: boolean;
changeDetection?: 'Default' | 'OnPush';
viewEncapsulation?: 'Emulated' | 'None' | 'ShadowDom';
displayBlock?: boolean;
selector?: string;
skipSelector?: boolean;
type?: string;
export?: boolean;
}
// Service schematic
interface ServiceSchematicOptions {
name: string;
path?: string;
project?: string;
skipTests?: boolean;
providedIn?: 'root' | 'platform' | 'any' | null;
}
// Directive schematic
interface DirectiveSchematicOptions {
name: string;
path?: string;
project?: string;
skipTests?: boolean;
standalone?: boolean;
selector?: string;
skipSelector?: boolean;
prefix?: string;
export?: boolean;
}// Module schematic
interface ModuleSchematicOptions {
name: string;
path?: string;
project?: string;
routing?: boolean;
routingScope?: 'Child' | 'Root';
commonModule?: boolean;
flat?: boolean;
module?: string;
}
// Guard schematic
interface GuardSchematicOptions {
name: string;
path?: string;
project?: string;
skipTests?: boolean;
implements?: ('CanActivate' | 'CanActivateChild' | 'CanDeactivate' | 'CanLoad')[];
functional?: boolean;
}// Generate component with custom options
await runSchematic({
collection: '@schematics/angular',
schematic: 'component',
options: {
name: 'user-profile',
standalone: true,
style: 'scss',
changeDetection: 'OnPush',
skipTests: false
}
});
// Generate service with DI configuration
await runSchematic({
collection: '@schematics/angular',
schematic: 'service',
options: {
name: 'user-data',
providedIn: 'root',
skipTests: false
}
});
// Generate module with routing
await runSchematic({
collection: '@schematics/angular',
schematic: 'module',
options: {
name: 'feature',
routing: true,
routingScope: 'Child'
}
});Support for installing and using third-party schematic collections.
# Install collection
npm install @angular/material
# Use collection schematics
ng add @angular/material
ng generate @angular/material:nav main-nav// Programmatic usage of third-party schematics
await runSchematic({
collection: '@angular/material',
schematic: 'nav',
options: {
name: 'main-nav'
}
});Interface for developing custom schematic collections.
/**
* Schematic collection metadata
*/
interface SchematicCollection {
name: string;
version: string;
description?: string;
schematics: Record<string, SchematicDescriptor>;
}
/**
* Individual schematic descriptor
*/
interface SchematicDescriptor {
name: string;
description: string;
factory: string;
schema?: string;
aliases?: string[];
hidden?: boolean;
private?: boolean;
}
/**
* Schematic validation result
*/
interface SchematicValidationResult {
isValid: boolean;
errors: Array<{
property: string;
message: string;
value?: any;
}>;
}Schematics can be configured at the workspace level in angular.json:
{
"schematics": {
"@schematics/angular:component": {
"style": "scss",
"skipTests": true,
"standalone": true
},
"@schematics/angular:service": {
"skipTests": false
}
}
}Project-specific schematic defaults:
{
"projects": {
"my-app": {
"schematics": {
"@schematics/angular:component": {
"changeDetection": "OnPush",
"style": "scss"
}
}
}
}
}Schematics respect CLI environment variables and configuration:
// Environment-aware schematic execution
const options = {
...getSchematicDefaults('@schematics/angular', 'component'),
name: 'my-component',
// Override defaults with environment-specific values
...(process.env.NODE_ENV === 'development' && {
skipTests: true
})
};
await runSchematic({
collection: '@schematics/angular',
schematic: 'component',
options
});Execute schematics without making file changes:
await runSchematic({
collection: '@schematics/angular',
schematic: 'component',
options: { name: 'test-component' },
dryRun: true // Shows what would be changed
});Override existing files and validation checks:
await runSchematic({
collection: '@schematics/angular',
schematic: 'component',
options: { name: 'existing-component' },
force: true // Overwrite existing files
});Access private or internal schematics:
await runSchematic({
collection: '@my-company/internal-schematics',
schematic: 'custom-component',
options: { name: 'internal-component' },
allowPrivate: true
});