
04 Feb 2026 Configuration Management in Node.Js
Configuration management is a fundamental part of building reliable and secure Node.js applications. As projects move from local to development and on to other environments, each requires its own settings: credentials, API keys, service URLs, etc. Managing these configurations properly prevents critical errors, deployment issues, or leaks, and a well-structured setup keeps sensitive data secure, separating application logic from environment-specific settings, vital to running the same codebase across different environments without manual changes.
This blog post explores the main principles and best practices for managing configuration in Node.js applications, focusing on environment variables, secret handling, and environment-specific settings.
Using Environment Variables
Environment variables are the foundation of configuration management in Node.js. They define operational parameters, such as ports, database credentials, and API endpoints. Rather than embedding these values, the application reads them at runtime, allowing the same codebase to adapt to different environments.
Example:
Const PORT = process.env.PORT || 3000;
App.listen(PORT, () => console.log(‘Server running on port ${PORT}’));
In local development, these variables are commonly stored in a .env file, which can be loaded into the environment using libraries like dotenv, dotenv-flow or dotenv-safe.
It is essential not to commit .env files to version control systems but to include them in the .gitignore file to ensure they remain local and are not inadvertently shared. Remember that .env files are typically intended only for local development, and in production and staging environments configuration values should be provided via deployment tools, container platforms such as Docker, or cloud environments such as Microsoft Azure, rather than through .env files.
Secure Management of Secrets and Sensitive Data
Whilst environment files offer convenience for local configurations, they are not suitable for storing confidential or sensitive information such as API keys, access tokens, or passwords.
In production environments, sensitive data must be stored and managed using a dedicated secret management system, for example Azure Key Vault or AWS Secrets Manager.
Secret managers enable the secure storage of credentials, fine-grained access control through identity-based authentication, and auditing capabilities that record access events and modifications.
The following table presents a practical comparison between handling configuration values locally with .env or securely managing them in Azure Key Vault:
| Configuration Step | Local Development (.env) | Production (Azure Key Vault) |
| Definition | Defined in a .env file on the local machine | Stored as a managed secret in the vault |
| Access method | Loaded from .env file and injected into process.env at startup | Retrieved from the vault and injected into process.env at runtime |
| Usage in code | process.env.API_KEY | process.env.API_KEY (after injection) |
| Security level | Low (local machine only) | High (encrypted, access-controlled) |
Example of a secret in .env locally:
# .env file
PORT=3000
DB_HOST=localhost
DB_USER=admin
DB_PASS=1234
API_KEY=local-test-key-123
# Read from Node.js
require('dotenv').config();
console.log('API Key:', process.env.API_KEY);
Example of a secret in Azure Key Vault:
# Creating environment variables az keyvault secret set \ --name API_KEY \ --vault-name MyKeyVault \ --value prod-key-abc-987654 # Read from Azure Key Vault export API_KEY=$(az keyvault secret show \ --vault-name MyKeyVault \ --name API_KEY \ --query value -o tsv)
Once injected, the secret is accessible through the standard process.env interface, guaranteeing consistency between local and production environments whilst maintaining security.
Integration with continuous integration and continuous delivery (CI/CD) systems, such as Azure DevOps or GitHub Actions, can be achieved via OpenID Connect (OIDC). This mechanism allows temporary, credential-free access to secrets, reducing exposure risks and removing the need for static credentials in pipelines.
Choosing Between .env, Secret Managers, and Runtime Variables
Different types of configuration require different handling strategies depending on their sensitivity, environment, and deployment context. The following table summarises common practices for local development versus staging/production:
| Type of Variable | Local (Development) | Staging / Production |
| Generic variables (PORT, LOG_LEVEL, NODE_ENV) | .env file (local configuration) | Environment variables configured via the hosting platform or CI/CD pipeline |
| Sensitive credentials (API keys, DB passwords) | .env file (for local testing only) | Secret manager / Key Vault (encrypted and access-controlled) |
| URLs and endpoints (API_URL, AUTH_URL, DB_HOST) | .env file | Environment variables configured in server or pipeline |
| Service-specific config (Redis, Storage, etc.) | .env file | Secret manager or environment variables configured in server/pipeline |
Using .env files in local development is convenient, but sensitive data should always be stored securely in secret managers in production. This approach reduces accidental leaks and improves deployment consistency.
Structuring Configuration in Large Projects
As applications grow, configuration management can become increasingly complex. A structured, centralised approach ensures consistency, maintainability, and security across environments.
Centralised Configuration Module
A common and effective strategy is to use the config package, which provides a structured and environment-aware configuration system. The package loads configuration files depending on the runtime environment, allowing overrides without code changes.
Example directory:
/config default.json production.json dev.json
Example of use:
const config = require('config');
const port = config.get('app.port');
const dbHost = config.get('db.host');
This centralised approach ensures cleaner deployments and easier maintenance.
Validation with Joi
Libraries like Joi allow the definition of validation schemas to ensure configuration integrity:
const Joi = require('joi');
const config = require('config');
const schema = Joi.object({
app: Joi.object({
port: Joi.number().required(),
logLevel: Joi.string().valid('debug', 'info', 'warn',
'error').default('info')
}),
db: Joi.object({
host: Joi.string().required(),
user: Joi.string().required(),
password: Joi.string().required()
})
});
Combining config for structured environment management with Joi for validation provides a scalable, maintainable, and secure configuration system, ideal for large Node.js applications.
Security and Maintenance Best Practices
Effective configuration management requires continuous attention to security and consistent operational practices. The following practices strengthen application security and reduce the risk of credential exposure:
- Secret rotation: Regularly update API keys and credentials to minimise exposure risks.
- Least privilege: Restrict access to configuration secrets only to required roles or services.
- Encryption: Protect secrets both at rest and during transmission.
- Audit and monitoring: Record access logs and detect unauthorised secret usage.
- Avoid logging sensitive data: Exclude credentials or tokens from logs and error messages.
Conclusion
Effective configuration management ensures Node.js applications remain secure, consistent, and easy to maintain. By separating configuration from code, using secret managers for sensitive data, and validating environment variables, developers can minimise risks and simplify deployments.
A structured configuration strategy allows the same application to adapt safely to any environment, from local development to production. Whether it’s a small application or a complex system, the basics remain the same: configuration must be separated from code, secure, and consistent.
At ClearPeaks, we develop dependable and scalable Node.js solutions tailored to your business needs. Our projects are built with security, performance, and growth in mind, so every application we deliver runs smoothly across local, staging, and production environments. Get in touch with us today to see how we can help you!

