Managing Environment Configurations in Angular 15+ Projects
Problem Statement
When creating new Angular projects with Angular CLI 15+, developers notice the environments folder (src/environments) is no longer generated by default. This folder previously contained essential configuration files (environment.ts, environment.prod.ts) for managing environment-specific settings like API endpoints and feature flags. Without this setup, developers must manually configure environment management for their applications.
The change reflects Angular's move toward simplified project structure, but leaves developers needing guidance on environment configuration best practices.
Recommended Solution: Angular CLI Environment Schematic
Use ng generate environments
Angular CLI 15.1+ introduced a dedicated schematic to generate environment files with proper configuration:
ng generate environmentsThis command:
- Creates the
src/environmentsfolder - Generates
environment.ts(default) - Creates
environment.prod.ts(production) - Updates
angular.jsonwith correct file replacements
Generated Folder Structure
src/
└── environments/
├── environment.ts # Development configuration
└── environment.prod.ts # Production configurationEnvironment File Content
Each environment file exports a constant object:
export const environment = {
production: false,
apiUrl: 'https://dev.api.example.com'
};export const environment = {
production: true,
apiUrl: 'https://api.example.com'
};Automatic angular.json Configuration
The CLI updates your workspace configuration:
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
// ... other production settings
}
}TIP
This command supports custom build configurations. For custom environments (e.g., staging), run:
ng generate environments --name=stagingAdding Environments Manually
If you need custom environment setups:
- Create the environments folder:bash
mkdir src/environments - Create environment files:bash
touch src/environments/environment.ts \ src/environments/environment.prod.ts \ src/environments/environment.staging.ts - Configure file replacements in
angular.json:json"configurations": { "production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ] }, "staging": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.staging.ts" } ] } }
WARNING
Manual setup requires careful configuration. Prefer ng generate environments to avoid human error in build configuration.
Alternative: Dynamic Runtime Environments
For projects requiring runtime environment variables (without rebuilds):
Create a build script (
build-scripts/env.js):javascriptconst fs = require('fs'); const path = require('path'); const envVars = Object.keys(process.env) .filter(key => key.startsWith('NG_APP_')) .reduce((acc, key) => ({ ...acc, [key]: process.env[key] }), {}); const fileContent = `(function(window) { window.__env = window.__env || {}; ${Object.entries(envVars) .map(([key, value]) => `window.__env.${key} = ${JSON.stringify(value)};`) .join('\n')} })(this);`; fs.writeFileSync( path.resolve(__dirname, '../src/assets/env.js'), fileContent );Include generated file in
angular.jsonassets:json"assets": [ { "glob": "env.js", "input": "src/assets", "output": "/assets" } ]Run script before build/serve scripts:
json"scripts": { "prebuild": "node build-scripts/env.js", "build": "ng build" }Add to
.gitignore::.gitignoresrc/assets/env.jsAccess variables in components:
typescriptdeclare const window: any; const apiUrl = window.__env.NG_APP_API_URL;
Tradeoffs
Pros:
- No rebuild required for environment changes
- CI/CD pipeline friendly
Cons:
- Variables exposed in client-side JavaScript
- Added build complexity
- Not Angular's standard approach
Migration Note for Angular 14 Projects
Existing projects upgrading to Angular 15 will retain their environments folder. No automatic migration is needed. New projects created with Angular 15+ require explicit environment setup.
Best Practices Summary
- For most projects:
ng generate environments - For custom configurations: Manual setup with file replacements
- For dynamic CI/CD environments: Runtime variable injection
- Always store sensitive variables server-side; never in client files
Why Environments Changed
Angular moved away from environment files by default to:
- Reduce unnecessary files in projects not needing environments
- Support more flexible configuration methods
- Align with future configuration improvements
For advanced workflows, see the official Angular Environment Configuration Guide.