Angular Budgets
Budgets set size limits on your build output. Angular warns or fails the build when a bundle exceeds the threshold, preventing accidental bloat from creeping in unnoticed.
Configuration (angular.json)
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kb",
"maximumError": "8kb"
}
]
}
}
Budget Types
| Type | What it measures |
|---|---|
initial | JS + CSS loaded on the initial page (most important) |
lazy | Any lazy-loaded chunk |
allScript | Sum of all JS scripts |
anyScript | Any single JS file |
any | Any single output file |
anyComponentStyle | The inline styles of a single component |
Warning vs Error
| Level | Behaviour |
|---|---|
maximumWarning | Build succeeds, warning printed |
maximumError | Build fails — CI pipeline blocked |
Set maximumWarning conservatively so you catch drift early. Set maximumError as the hard cap.
Analyzing What's Inside the Bundle
When a budget is exceeded, find the culprit:
# Step 1: generate the stats file
ng build --stats-json
# Step 2: visualize it
npx webpack-bundle-analyzer dist/my-app/browser/stats.json
Common causes of oversized bundles:
- Importing an entire library instead of specific functions (
import * as _ from 'lodash') - A large third-party dependency loaded eagerly instead of lazily
- Duplicate dependencies (different versions of the same package)
Quick Fixes
// ❌ Imports the whole library (~70 kb)
import * as _ from 'lodash';
// ✅ Tree-shakeable — only what you use
import { debounce } from 'lodash-es';
// ❌ Eager — increases initial bundle
import { ChartModule } from 'chart.js';
// ✅ Lazy — loaded only when needed
const { Chart } = await import('chart.js');
Recommended Starting Budgets
| App type | initial warning | initial error |
|---|---|---|
| Landing / marketing | 150 kb | 250 kb |
| Standard app | 400 kb | 800 kb |
| Feature-rich dashboard | 600 kb | 1 mb |
Configure budgets at project creation — retrofitting them on a large app is painful.