> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/angular/angular/llms.txt
> Use this file to discover all available pages before exploring further.

# Angular CLI Builders

> Understanding and customizing Angular build processes with Architect builders

## What are Builders?

Builders are the underlying execution engine for Angular CLI commands. They are part of the Angular Architect API and define how commands like `ng build`, `ng test`, and `ng serve` actually work. Each builder is a function that performs a specific task according to a target configuration defined in `angular.json`.

<Info>
  Builders are similar to webpack plugins or Gulp tasks - they're modular units that perform specific build operations.
</Info>

## Builder Architecture

The Angular CLI uses the **Architect** system to run builders:

```mermaid theme={null}
graph LR
    A[ng build] --> B[Architect]
    B --> C[Builder]
    C --> D[Build Output]
```

### Key Concepts

<CardGroup cols={2}>
  <Card title="Target" icon="bullseye">
    A named builder configuration in angular.json (e.g., "build", "test")
  </Card>

  <Card title="Builder" icon="hammer">
    The actual implementation that performs the work
  </Card>

  <Card title="Options" icon="sliders">
    Configuration parameters passed to the builder
  </Card>

  <Card title="Configurations" icon="layer-group">
    Named option overrides (e.g., "production", "development")
  </Card>
</CardGroup>

## Official Builders

Angular provides several official builders:

### Application Builders

<Tabs>
  <Tab title="@angular/build:application">
    The modern application builder (Angular v17+) using esbuild and Vite.

    ```json theme={null}
    {
      "architect": {
        "build": {
          "builder": "@angular/build:application",
          "options": {
            "outputPath": {
              "base": "dist",
              "browser": ""
            },
            "index": "src/index.html",
            "browser": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
      }
    }
    ```

    **Features:**

    * Fast builds with esbuild
    * Improved development server
    * Better optimization
    * SSR/SSG support out of the box
  </Tab>

  <Tab title="@angular-devkit/build-angular:browser">
    Traditional browser application builder using webpack.

    ```json theme={null}
    {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/my-app",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
      }
    }
    ```

    **Use cases:**

    * Legacy projects
    * Custom webpack configurations
    * Specific webpack plugins required
  </Tab>
</Tabs>

<Note>
  Angular v17+ recommends using `@angular/build:application` for new projects.
</Note>

***

### Development Server Builders

#### @angular/build:dev-server

Development server for the application builder:

```json theme={null}
{
  "architect": {
    "serve": {
      "builder": "@angular/build:dev-server",
      "options": {
        "buildTarget": "my-app:build"
      },
      "configurations": {
        "production": {
          "buildTarget": "my-app:build:production"
        },
        "development": {
          "buildTarget": "my-app:build:development"
        }
      }
    }
  }
}
```

**Key Options:**

* `buildTarget`: Which build configuration to serve
* `port`: Development server port
* `host`: Host address
* `ssl`: Enable HTTPS
* `proxyConfig`: API proxy configuration

***

### Test Builder

#### @angular-devkit/build-angular:karma

Runs unit tests with Karma:

```json theme={null}
{
  "architect": {
    "test": {
      "builder": "@angular-devkit/build-angular:karma",
      "options": {
        "polyfills": ["zone.js", "zone.js/testing"],
        "tsConfig": "tsconfig.spec.json",
        "karmaConfig": "karma.conf.js",
        "assets": ["src/favicon.ico", "src/assets"],
        "styles": ["src/styles.css"],
        "scripts": []
      }
    }
  }
}
```

**Options:**

* `karmaConfig`: Path to Karma configuration
* `watch`: Watch files for changes
* `codeCoverage`: Generate coverage reports
* `browsers`: Browsers to run tests in

<Tip>
  The Angular team uses Karma 6.4.0 for testing in the source repository.
</Tip>

***

### Internationalization Builder

#### @angular/build:extract-i18n

Extracts i18n messages from templates:

```json theme={null}
{
  "architect": {
    "extract-i18n": {
      "builder": "@angular/build:extract-i18n",
      "options": {
        "buildTarget": "my-app:build"
      }
    }
  }
}
```

***

### Lint Builder

#### @angular/build:tslint

Runs TSLint on the project:

```json theme={null}
{
  "architect": {
    "lint": {
      "builder": "@angular/build:tslint",
      "options": {
        "tsConfig": [
          "tsconfig.app.json",
          "tsconfig.spec.json"
        ],
        "exclude": ["**/node_modules/**"]
      }
    }
  }
}
```

<Warning>
  TSLint is deprecated. Consider migrating to ESLint with `@angular-eslint`.
</Warning>

***

## Builder Options

### Common Options

These options are available across multiple builders:

<AccordionGroup>
  <Accordion title="Output Configuration">
    <ParamField path="outputPath" type="string | object">
      Where to write build output files
    </ParamField>

    <ParamField path="outputHashing" type="string">
      Hash output files for cache busting: `none`, `all`, `media`, `bundles`
    </ParamField>
  </Accordion>

  <Accordion title="Source Files">
    <ParamField path="index" type="string">
      Path to index.html file
    </ParamField>

    <ParamField path="browser" type="string">
      Main browser entry point (for application builder)
    </ParamField>

    <ParamField path="main" type="string">
      Main entry point (for browser builder)
    </ParamField>

    <ParamField path="polyfills" type="string[]">
      Polyfills to include
    </ParamField>
  </Accordion>

  <Accordion title="TypeScript Configuration">
    <ParamField path="tsConfig" type="string">
      Path to TypeScript configuration file
    </ParamField>

    <ParamField path="aot" type="boolean" default="true">
      Enable Ahead-of-Time compilation
    </ParamField>
  </Accordion>

  <Accordion title="Assets & Resources">
    <ParamField path="assets" type="array">
      Static assets to copy

      ```json theme={null}
      "assets": [
        "src/favicon.ico",
        "src/assets",
        {
          "glob": "**/*",
          "input": "src/assets/",
          "output": "/assets/"
        }
      ]
      ```
    </ParamField>

    <ParamField path="styles" type="array">
      Global stylesheets to include
    </ParamField>

    <ParamField path="scripts" type="array">
      Global scripts to include
    </ParamField>
  </Accordion>

  <Accordion title="Optimization">
    <ParamField path="optimization" type="boolean | object">
      Enable optimization (minification, tree-shaking)

      ```json theme={null}
      "optimization": {
        "scripts": true,
        "styles": true,
        "fonts": true
      }
      ```
    </ParamField>

    <ParamField path="sourceMap" type="boolean">
      Generate source maps
    </ParamField>

    <ParamField path="namedChunks" type="boolean">
      Use human-readable chunk names
    </ParamField>

    <ParamField path="extractLicenses" type="boolean">
      Extract third-party licenses to separate file
    </ParamField>
  </Accordion>

  <Accordion title="Performance Budgets">
    <ParamField path="budgets" type="array">
      Size budgets for application

      ```json theme={null}
      "budgets": [
        {
          "type": "initial",
          "maximumWarning": "2mb",
          "maximumError": "5mb"
        },
        {
          "type": "anyComponentStyle",
          "maximumWarning": "6kb",
          "maximumError": "10kb"
        }
      ]
      ```
    </ParamField>
  </Accordion>
</AccordionGroup>

***

## Build Configurations

Configurations are named sets of option overrides:

```json theme={null}
{
  "architect": {
    "build": {
      "builder": "@angular/build:application",
      "options": {
        "outputHashing": "none",
        "optimization": false,
        "sourceMap": true
      },
      "configurations": {
        "production": {
          "optimization": true,
          "outputHashing": "all",
          "sourceMap": false,
          "namedChunks": false,
          "extractLicenses": true,
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "2mb",
              "maximumError": "5mb"
            }
          ]
        },
        "development": {
          "optimization": false,
          "sourceMap": true,
          "namedChunks": true
        }
      },
      "defaultConfiguration": "production"
    }
  }
}
```

### Using Configurations

```bash theme={null}
# Use production configuration
ng build --configuration=production
ng build -c production

# Use development configuration
ng build --configuration=development
```

***

## Custom Builders

You can create custom builders for specialized build tasks.

### Creating a Custom Builder

<Steps>
  <Step title="Create Builder Package">
    ```bash theme={null}
    ng generate library my-builder
    ```
  </Step>

  <Step title="Define Builder Schema">
    Create `schema.json`:

    ```json theme={null}
    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "type": "object",
      "properties": {
        "option1": {
          "type": "string",
          "description": "An example option"
        }
      },
      "required": ["option1"]
    }
    ```
  </Step>

  <Step title="Implement Builder">
    ```typescript theme={null}
    import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
    import { JsonObject } from '@angular-devkit/core';

    interface Options extends JsonObject {
      option1: string;
    }

    async function myBuilder(
      options: Options,
      context: BuilderContext
    ): Promise<BuilderOutput> {
      context.reportStatus(`Running with option: ${options.option1}`);
      
      // Perform build tasks
      try {
        // Your build logic here
        return { success: true };
      } catch (error) {
        context.reportStatus('Error: ' + error.message);
        return { success: false };
      }
    }

    export default createBuilder(myBuilder);
    ```
  </Step>

  <Step title="Register Builder">
    Add to `builders.json`:

    ```json theme={null}
    {
      "builders": {
        "my-builder": {
          "implementation": "./src/builder.ts",
          "schema": "./src/schema.json",
          "description": "My custom builder"
        }
      }
    }
    ```
  </Step>

  <Step title="Use in angular.json">
    ```json theme={null}
    {
      "architect": {
        "custom": {
          "builder": "my-library:my-builder",
          "options": {
            "option1": "value"
          }
        }
      }
    }
    ```
  </Step>
</Steps>

### Running Custom Builder

```bash theme={null}
ng run my-app:custom
```

***

## Builder Context

Builders receive a `BuilderContext` with useful utilities:

```typescript theme={null}
interface BuilderContext {
  // Logging
  logger: Logger;
  reportStatus(status: string): void;
  reportProgress(current: number, total?: number, status?: string): void;
  
  // Workspace information
  workspaceRoot: string;
  currentDirectory: string;
  
  // Target information
  target?: Target;
  
  // Schedule other builders
  scheduleBuilder(builder: string, options: JsonObject): Promise<BuilderRun>;
  scheduleTarget(target: Target, overrides?: JsonObject): Promise<BuilderRun>;
  
  // Get target options
  getTargetOptions(target: Target): Promise<JsonObject>;
  
  // Validate options
  validateOptions<T extends JsonObject>(options: JsonObject, builderName: string): Promise<T>;
}
```

***

## File Replacements

Replace files during build based on configuration:

```json theme={null}
{
  "configurations": {
    "production": {
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ]
    }
  }
}
```

<Tip>
  Useful for environment-specific configurations.
</Tip>

***

## Build Optimization Strategies

### Code Splitting

```json theme={null}
{
  "optimization": true,
  "namedChunks": false,
  "commonChunk": true
}
```

### Tree Shaking

Enabled automatically with optimization:

```json theme={null}
{
  "optimization": {
    "scripts": true
  }
}
```

### Differential Loading

Generate separate bundles for modern and legacy browsers:

```json theme={null}
{
  "tsConfig": "tsconfig.app.json",
  "browserslist": ".browserslistrc"
}
```

***

## Performance Budgets

Set size limits to maintain performance:

<Tabs>
  <Tab title="Initial Budget">
    ```json theme={null}
    {
      "type": "initial",
      "maximumWarning": "2mb",
      "maximumError": "5mb"
    }
    ```

    Total size of initial bundle.
  </Tab>

  <Tab title="Component Styles">
    ```json theme={null}
    {
      "type": "anyComponentStyle",
      "maximumWarning": "6kb",
      "maximumError": "10kb"
    }
    ```

    Size of individual component styles.
  </Tab>

  <Tab title="All Scripts">
    ```json theme={null}
    {
      "type": "allScript",
      "maximumWarning": "500kb",
      "maximumError": "1mb"
    }
    ```

    Total size of all scripts.
  </Tab>

  <Tab title="Lazy Bundles">
    ```json theme={null}
    {
      "type": "anyComponentStyle",
      "maximumWarning": "100kb",
      "maximumError": "200kb"
    }
    ```

    Size of lazy-loaded bundles.
  </Tab>
</Tabs>

***

## Proxy Configuration

Configure API proxying for development:

**proxy.conf.json:**

```json theme={null}
{
  "/api": {
    "target": "http://localhost:3000",
    "secure": false,
    "changeOrigin": true,
    "pathRewrite": {
      "^/api": ""
    }
  }
}
```

**angular.json:**

```json theme={null}
{
  "serve": {
    "options": {
      "proxyConfig": "proxy.conf.json"
    }
  }
}
```

***

## Build Events

Builders emit events during execution:

```typescript theme={null}
import { BuilderOutput } from '@angular-devkit/architect';
import { Observable } from 'rxjs';

function myBuilder(options: Options): Observable<BuilderOutput> {
  return new Observable(subscriber => {
    // Emit progress
    subscriber.next({ success: false, progress: 0.5 });
    
    // Complete build
    subscriber.next({ success: true });
    subscriber.complete();
  });
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Schematics" icon="wand-magic-sparkles" href="/cli/schematics">
    Create custom code generators
  </Card>

  <Card title="CLI Commands" icon="terminal" href="/cli/commands">
    Master all Angular CLI commands
  </Card>
</CardGroup>

## Resources

<CardGroup cols={2}>
  <Card title="Architect API" icon="book" href="https://angular.dev/tools/cli/cli-builder">
    Official builder documentation
  </Card>

  <Card title="Builder Examples" icon="github" href="https://github.com/angular/angular-cli/tree/main/packages/angular_devkit/build_angular">
    Angular DevKit builders source
  </Card>
</CardGroup>
