nx-config2
v3.6.5
Published
Next-generation configuration management for Node.js - Zero dependencies, TypeScript-first, production-ready
Maintainers
Readme
nx-config2 🚀
Configuration Normalizer for Node.js
Normalize diverse configuration sources into a consistent, type-safe structure.
Zero dependencies. TypeScript-first. Production-ready.
nxconfig combines the best features from 9+ MIT-licensed configuration libraries into one powerful, zero-dependency package. Perfect for cloud-native applications, microservices, and enterprise systems.
🧰 Toolbox of Pre-Configuration
nx-config2 provides Out-of-the-Box (OOTB) Presets - a toolbox of pre-configured patterns designed to create a common ground for configuration across different projects and use cases.
What This Means
- Toolbox Approach: Pre-configured patterns for common infrastructure needs (MongoDB, Redis, S3/Spaces)
- Specific Support Out of the Box: Ready-made configuration normalization for role-based databases, caches, and storage
- Doesn't Prevent Other Stuff: Fully flexible - custom config maps work alongside presets
- Common Ground from One Place: All OOTB parts are already preconfigured with standardized structure, naming, and fallback logic
- Optional Until Used: Nothing is required - use what you need, ignore what you don't
OOTB Presets Include
- MongoDB: Role-based database configuration with shared connection defaults and per-role overrides
- Redis: Role-based cache configuration with connection and DB index management
- S3/Spaces Storage: Role-based bucket configuration with purpose buckets (backup, records, versions, content)
All presets include deterministic fallback chains and are fully optional. See OOTB_PRESETS_DESIGN.md for complete documentation.
✨ Why nxconfig?
nxconfig is a configuration normalizer that transforms diverse configuration inputs (different naming conventions, formats, sources) into a consistent, predictable structure. It combines the best features from 9+ popular MIT-licensed packages into one powerful, zero-dependency solution.
Core Normalization Features:
- Variable Name Normalization: Accepts multiple naming conventions (e.g.,
MONGO_URI,MONGODB_URI,MONGO_URL) → normalizes toconfig.database.mongodb.uri - Type Normalization: Automatically coerces strings to proper types (number, boolean, array, json, etc.) with validation
- Priority Normalization: 3-tier fallback system (AI-specific → feature-specific → base/default)
- Case Normalization: Converts
SCREAMING_SNAKE_CASEenv vars tocamelCaseconfig paths - Source Normalization: Unifies configuration from env vars, files, secrets, CLI args into one structure
- Structure Normalization: Provides consistent, predictable configuration structure with TypeScript IntelliSense
Additional Capabilities:
- ENV Token Resolution with multi-environment file support
- Schema Validation with detailed error reporting
- Multi-Config Merging with intelligent conflict resolution
- Environment Variable Inspection with sensitive data masking
- Hot Reload and Auto-Documentation generation
🎯 Configuration Normalization Strategy
What is Configuration Normalization?
Configuration normalization is the process of transforming diverse configuration inputs (different naming conventions, formats, types, sources) into a consistent, predictable structure that your application can reliably consume.
The Problem:
- Different projects use different variable names (
MONGO_URIvsMONGODB_URIvsMONGO_URL) - Environment variables are always strings, but you need proper types (numbers, booleans, arrays)
- Configuration comes from multiple sources (env vars, files, secrets, CLI args)
- Different environments need different specificity levels (development vs production vs feature-specific)
The Solution: nx-config2 normalizes all these variations into a single, consistent configuration structure with proper types, predictable paths, and TypeScript IntelliSense support.
Normalization Dimensions
1. Variable Name Normalization
Multiple naming conventions for the same configuration are normalized to a single path:
// Accepts ANY of these variable names:
// - MONGO_URI
// - MONGO_URL
// - MONGODB_URI
// - XRONOX_MONGO_URI
// All normalize to:
config.database.mongodb.uriExample:
// In your config map:
uri: 'ENV.MONGO_URI||ENV.MONGO_URL||ENV.MONGODB_URI||default-value'
// Result: Single config path regardless of which variable is set2. Type Normalization
String values from environment variables are automatically coerced to proper types with validation:
// Input (string): "8080"
port: 'ENV.PORT:port||3000'
// Normalized Output (number): 8080
// Validated: Must be 0-65535Supported Types:
- Numbers:
number,int,nat,port,bigint - Booleans:
boolean(accepts "true"/"false", "1"/"0", "yes"/"no") - Collections:
array,json - Formats:
duration,bytes,url,email,ipaddress,regex
3. Priority Normalization (3-Tier Fallback)
Different specificity levels are normalized through a hierarchical fallback system:
// Tier 1: Application/Feature-Specific (Highest Priority)
// Tier 2: Role/Feature-Specific (Medium Priority)
// Tier 3: Base/Default (Lowest Priority)
logsUri: 'ENV.MONGO_AI_LOGS_URI||ENV.MONGO_LOGS_URI||ENV.MONGO_URI||...'How It Works:
- First checks for Tier 1 (most specific)
- Falls back to Tier 2 if Tier 1 not found
- Falls back to Tier 3 (base/default) if Tier 2 not found
- Uses hardcoded default if none found
Example:
# Scenario 1: Tier 1 set
MONGO_AI_LOGS_URI=mongodb://ai-logs:27017
# Result: Uses ai-logs (Tier 1)
# Scenario 2: Only Tier 2 set
MONGO_LOGS_URI=mongodb://logs:27017
# Result: Uses logs (Tier 2)
# Scenario 3: Only Tier 3 set
MONGO_URI=mongodb://base:27017
# Result: Uses base (Tier 3)4. Case Normalization
Environment variables use SCREAMING_SNAKE_CASE, but configuration uses camelCase:
// Input: MONGO_URI, REDIS_HOST, API_TIMEOUT
// Normalized: { mongoUri, redisHost, apiTimeout }5. Source Normalization
Configuration from multiple sources is unified into a single structure:
Sources Supported:
- Environment variables (
process.env) .envfiles (with shared .env support)- Secret management systems (ATM)
- Command-line arguments
- Configuration files (JSON, JS)
- Remote configuration
Result: Single config object regardless of source.
6. Structure Normalization
All configuration follows a consistent, predictable hierarchy:
// All database configurations normalize to:
config.database.mongodb.uri
config.database.mongodb.database
config.database.mongodb.roles.runtime.connectionString
// All API configurations normalize to:
config.api.port
config.api.host
config.api.timeoutBenefits:
- Predictable paths across projects
- TypeScript IntelliSense support
- Easy to navigate and understand
7. Format Normalization
Same value represented in different formats is normalized to a standard format:
// Duration: "30s", "1m", "500ms" → 30000 (milliseconds)
timeout: 'ENV.TIMEOUT:duration||30s'
// Array: "tag1,tag2,tag3" → ["tag1", "tag2", "tag3"]
tags: 'ENV.TAGS:array'
// Boolean: "true", "1", "yes" → true
enabled: 'ENV.ENABLED:boolean'Normalization Patterns
Pattern 1: Multi-Variable Fallback
Support legacy and new variable names:
apiKey: 'ENV.OPENAI_API_KEY||ENV.OPENAI_KEY||ATM.SECRET.openai-key'Pattern 2: 3-Tier Priority Fallback
Support different specificity levels:
// Application-specific → Feature-specific → Base/default
logsUri: 'ENV.MONGO_AI_LOGS_URI||ENV.MONGO_LOGS_URI||ENV.MONGO_URI'Pattern 3: Type + Default Normalization
Ensure type safety with sensible defaults:
// Always results in a valid port number (0-65535)
port: 'ENV.PORT:port||8080'Normalization Rules
- First Match Wins: When multiple fallback options are available, the first non-empty value is used
- Type Coercion Always Applied: String values are automatically coerced to the specified type with validation
- Defaults Always Provided: If no value is found, a sensible default is used (if specified)
- Validation on Normalization: Type validation occurs during normalization, ensuring invalid values are caught early
- Case Preservation in Paths: Config paths preserve the structure defined in the map, regardless of input case
Benefits of Normalization
✅ Developer Experience: Consistent API regardless of input, TypeScript IntelliSense support, predictable structure
✅ Flexibility: Support multiple naming conventions, backward compatible with legacy configs, easy migration paths
✅ Reliability: Type safety, validation at normalization time, clear error messages
✅ Maintainability: Single source of truth for structure, centralized normalization rules, easy to extend
Real-World Example
Input Variations:
# Different naming conventions
MONGO_URI=mongodb://localhost:27017
MONGO_DB=myapp
# Or feature-specific
MONGO_LOGS_URI=mongodb://logs:27017
MONGO_LOGS_DB=logs-db
# Or application-specific
MONGO_AI_LOGS_URI=mongodb://ai-logs:27017
MONGO_AI_LOGS_DB=ai-activitiesNormalized Output:
{
database: {
mongodb: {
logsUri: 'mongodb://ai-logs:27017', // Tier 1 wins
logsDatabase: 'ai-activities' // Tier 1 wins
}
}
}Type Normalization Example:
# Input (all strings)
PORT=8080
ENABLED=true
TIMEOUT=30s
TAGS=tag1,tag2// Normalized Output (proper types)
{
port: 8080, // number
enabled: true, // boolean
timeout: 30000, // number (milliseconds)
tags: ['tag1', 'tag2'] // array
}📦 Installation
npm install nx-config2yarn add nx-config2pnpm add nx-config2🖥️ CLI Usage (Cross-Platform Execution)
nxconfig provides a powerful CLI tool to execute scripts with environment variables in a cross-platform way (Windows/Linux/macOS), eliminating the need for packages like cross-env.
Running Commands
# Works on Windows, macOS, and Linux
npx nx-config2 run --env ENABLE_LOGGING=true -- node script.jsOptions
| Option | Description |
|--------|-------------|
| --env KEY=VALUE | Set an environment variable (can be used multiple times) |
| --env-file .env | Load environment variables from a file |
| --verbose | Enable verbose logging |
Use in package.json
{
"scripts": {
"test": "nx-config2 run --env NODE_ENV=test --env DEBUG=true -- jest",
"start": "nx-config2 run --env-file .env.prod -- node dist/index.js"
}
}📋 Variable Metadata
nxconfig now includes a standard metadata definitions file for common environment variables, promoting consistency across projects.
- Common Variables:
metadata/common-variables.json - Schema:
metadata/schema.json
You can use these definitions as a reference for naming conventions and type configurations.
🚀 Quick Start
nxConfig API (NEW! - Intelligent Configuration Management)
The nxConfig API provides intelligent configuration management with nested properties, type coercion, and advanced features:
import { nxConfig } from 'nx-config2';
// Simple variable access
const apiUrl = nxConfig.API_URL;
const port = nxConfig.PORT;
const debugMode = nxConfig.DEBUG_MODE;
// Nested property access
const database = nxConfig.database;
// Returns: {
// host: 'localhost',
// port: 5432,
// user: 'admin',
// password: '***',
// pool: { min: 2, max: 10 }
// }
// Deep nested access
const googleClientId = nxConfig.features.authentication.oauth.google.clientId;
// Type-safe access with automatic coercion
const port = nxConfig.server.port; // Automatically converted to number
const enabled = nxConfig.features.analytics; // Automatically converted to boolean
const hosts = nxConfig.allowedHosts; // Automatically converted to arrayKey Features:
- ✅ Nested Properties: Access deeply nested configuration with dot notation
- ✅ Type Coercion: Automatic conversion (string → number, boolean, array, JSON)
- ✅ Secret Management: Automatic masking of sensitive data
- ✅ Configuration Files: Load from JavaScript, JSON, YAML, TOML files
- ✅ Environment Variables: Automatic mapping with
__for nesting - ✅ Hot Reload: Watch files and reload automatically
- ✅ Version History: Track configuration changes
- ✅ Multi-Tenancy: Support for tenant-specific configuration
- ✅ Export/Import: Export to JSON, YAML, .env formats
Basic Usage (Traditional API)
import { initConfig } from 'nx-config2';
// Set environment variables
process.env.DB_HOST = 'localhost';
process.env.DB_PORT = '5432';
process.env.API_KEY = 'secret123';
const config = {
database: {
host: 'ENV.DB_HOST',
port: 'ENV.DB_PORT:port', // Auto-validates port range
password: 'ENV.DB_PASSWORD||changeme' // Default value
},
api: {
key: 'ENV.API_KEY',
timeout: 'ENV.TIMEOUT:duration||30s' // Parses "30s" to 30000ms
}
};
const result = initConfig(config, {
dotenvPath: '.env',
verbose: true
});
console.log(result.config);
// {
// database: { host: 'localhost', port: 5432, password: 'changeme' },
// api: { key: 'secret123', timeout: 30000 }
// }🎯 Core Features
1. ENV Token Resolution
Use ENV.VARIABLE tokens in your configuration:
const config = {
service: 'ENV.SERVICE_NAME',
port: 'ENV.PORT:number||3000'
};1.1. Multi-Environment File Support (NEW!)
Load variables from different environment files based on the token pattern:
const config = {
// Simple pattern: loads from .env or process.env
app: {
name: 'ENV.APP_NAME||my-app',
version: 'ENV.APP_VERSION||1.0.0'
},
// Multi-segment pattern: loads from .env.test file
test: {
apiKey: 'ENV.TEST.API_KEY',
dbHost: 'ENV.TEST.DB_HOST',
dbPort: 'ENV.TEST.DB_PORT:port'
},
// Multi-segment pattern: loads from .env.prod.database file
production: {
database: {
host: 'ENV.PROD.DATABASE.HOST',
port: 'ENV.PROD.DATABASE.PORT:port',
ssl: 'ENV.PROD.DATABASE.SSL:boolean'
}
}
};Pattern Rules:
ENV.VARIABLE→ loads from.envfile orprocess.envENV.TEST.VARIABLE→ loads from.env.testfileENV.PROD.DATABASE.HOST→ loads from.env.prod.databasefileENV.STAGING.API.KEY→ loads from.env.staging.apifile
The last segment is always the variable name, everything before it becomes the environment file path.
2. Type Coercion (15+ Built-in Types)
nxconfig provides comprehensive type coercion with built-in validation for 15+ data types. Each type includes validation, error handling, and automatic conversion:
'ENV.PORT:port' // Validates 0-65535, throws error if invalid
'ENV.ENABLED:boolean' // Converts 'true'/'false', '1'/'0' to boolean
'ENV.COUNT:number' // Converts to number, validates not NaN
'ENV.COUNT:int' // Integer only, validates whole numbers
'ENV.COUNT:nat' // Natural number (>=0), validates non-negative
'ENV.MAX:bigint' // BigInt support for large numbers
'ENV.TAGS:array' // Comma-separated string to array
'ENV.DATA:json' // JSON parsing with error handling
'ENV.URL:url' // URL validation using native URL constructor
'ENV.EMAIL:email' // Email validation with regex pattern
'ENV.IP:ipaddress' // IPv4/IPv6 address validation
'ENV.TIMEOUT:duration' // Duration parsing: "5s", "10m", "2h", "1d", "1w"
'ENV.DATE:timestamp' // Date parsing, returns milliseconds
'ENV.PATTERN:regex' // RegExp compilation with error handlingType Validation Features:
- Automatic Error Handling: Invalid values throw descriptive errors
- Range Validation: Port numbers (0-65535), natural numbers (≥0)
- Format Validation: Email, URL, IP address patterns
- Custom Validators: Extend with your own validation functions
- Null Safety: Handles undefined/null values gracefully
3. Default Values
nxconfig supports comprehensive default value handling with multiple fallback strategies:
'ENV.HOST||localhost' // Simple default value
'ENV.PORT:number||3000' // Default with type coercion
'ENV.DEBUG:boolean||false' // Boolean default
'ENV.TIMEOUT:duration||30s' // Duration default
'ENV.TAGS:array||item1,item2' // Array defaultDefault Value Features:
- Multiple Fallback Levels: ENV variable → default value → options defaults
- Type-Aware Defaults: Defaults are processed through type coercion
2.1. Automatic JSON-like Parsing (NEW!)
nxconfig automatically detects and parses JSON-like strings in environment variables, even without explicit type annotations. Values that start with { and end with } are parsed as objects, and values that start with [ and end with ] are parsed as arrays.
Object Parsing:
// .env file
DATABASE_CONFIG={"host":"localhost","port":5432,"ssl":true}
// Config
const config = {
database: 'ENV.DATABASE_CONFIG' // Automatically parsed as object
};
// Result
// { database: { host: 'localhost', port: 5432, ssl: true } }Array Parsing:
// .env file
ALLOWED_HOSTS=["localhost","example.com","127.0.0.1"]
PORT_NUMBERS=[3000,8080,9000]
COMPLEX_ARRAY=[{"name":"server1","port":3000},{"name":"server2","port":8080}]
// Config
const config = {
hosts: 'ENV.ALLOWED_HOSTS', // String array
ports: 'ENV.PORT_NUMBERS', // Number array
servers: 'ENV.COMPLEX_ARRAY' // Array of objects
};
// Result
// {
// hosts: ['localhost', 'example.com', '127.0.0.1'],
// ports: [3000, 8080, 9000],
// servers: [{ name: 'server1', port: 3000 }, { name: 'server2', port: 8080 }]
// }Fallback Behavior:
- If parsing fails (invalid JSON), the original string value is returned
- This ensures no errors occur when a string happens to start with
{or[but isn't JSON
// .env file
NOT_JSON={not valid json
// Config
const config = {
value: 'ENV.NOT_JSON' // Returns "{not valid json" (string)
};Array Type Enhancement:
The array type now supports both JSON arrays and comma-separated strings:
// JSON array (parsed as typed array)
ENV.ITEMS:array with value "[1,2,3]" → [1, 2, 3] (numbers)
// Comma-separated string (split and trimmed)
ENV.ITEMS:array with value "a,b,c" → ['a', 'b', 'c'] (strings)2.2. JSON File References (NEW!)
nxconfig supports referencing external JSON files directly from environment variables using the {{path.json}} syntax. This is useful for complex configurations that are better stored in separate files.
File Reference Pattern:
// .env file
DATABASE_CONFIG={{./configuration-examples/database.json}}
SERVER_LIST={{./configs/servers.json}}
// Config
const config = {
database: 'ENV.DATABASE_CONFIG', // Loads from ./configuration-examples/database.json
servers: 'ENV.SERVER_LIST' // Loads from ./configs/servers.json
};
// Result - automatically loads and parses the JSON files
// {
// database: { host: 'localhost', port: 5432, ... },
// servers: [{ name: 'server1', port: 3000 }, ...]
// }Path Resolution:
- Paths are resolved relative to the config file location (if parsing from a file)
- Otherwise, paths are resolved relative to
process.cwd() - Supports both relative paths (
./config.json) and absolute paths (/absolute/path.json)
Fallback Behavior:
- If the file doesn't exist, the original string value
{{path.json}}is returned - If the file exists but contains invalid JSON, the original string is returned
- This ensures no errors occur when files are missing or malformed
// .env file
MISSING_FILE={{./nonexistent.json}}
// Config
const config = {
value: 'ENV.MISSING_FILE' // Returns "{{./nonexistent.json}}" (string)
};Configuration Options:
heuristicJsonParsing: Enable/disable automatic JSON detection (including file references) (default:true)lenientJson: When using:jsontype, return original string on parse failure instead of throwing (default:false)
// Disable automatic JSON parsing (including file references)
parseConfig(config, { heuristicJsonParsing: false });
// Use lenient JSON parsing (no errors on invalid JSON)
parseConfig(config, { lenientJson: true });2.3. Config Object File References (NEW!)
nxconfig supports loading JSON files directly from config objects using the reserved _loadFile property. This allows you to reference external JSON files in your configuration structure.
Config File Reference Pattern:
const config = {
// Load entire object from file
database: { _loadFile: './configs/database.json' },
// Load entire array from file
servers: { _loadFile: './configs/servers.json' },
// Mix file references with direct values
app: {
name: 'my-app',
config: { _loadFile: './configs/app-config.json' }
}
};
// Result - automatically loads and parses JSON files
// {
// database: { host: 'localhost', port: 5432, ... },
// servers: [{ name: 'server1', port: 3000 }, ...],
// app: {
// name: 'my-app',
// config: { timeout: 5000, ... }
// }
// }Important Notes:
_loadFileis a reserved property name - when present, the entire object is replaced with the file's contents- File contents can be either JSON objects or JSON arrays
- Paths are resolved relative to the config file location (if parsing from a file) or
process.cwd()(if parsing from an object) - If the file doesn't exist or contains invalid JSON, the original object (with
_loadFile) is returned and a warning is generated - The loaded content is recursively parsed, so it can contain ENV tokens, nested
_loadFilereferences, etc.
Example from Config File:
{
"database": { "_loadFile": "./database.json" },
"servers": { "_loadFile": "./servers.json" }
}- Warning System: Logs when defaults are used for transparency
- Nested Defaults: Support for complex default structures
3. Automatic Config Loading (NEW!)
nxconfig provides an automatic config loader that uses a default config map covering common use cases, then automatically adds any additional environment variables as camelCase properties at the root level.
Basic Usage:
import { autoLoadConfig } from 'nx-config2';
// Automatically load all config from environment variables
const config = autoLoadConfig();
// Access structured config
console.log(config.api.port); // From ENV.API_PORT
console.log(config.database.uri); // From ENV.MONGO_URI
console.log(config.logging.level); // From ENV.LOG_LEVEL
// Additional env vars automatically added as camelCase
// ENV.CUSTOM_VAR → config.customVar
// ENV.MY_APP_VAR → config.myAppVarDefault Config Map: The auto-loader includes a pre-configured map covering:
api: port, allowedCollections, mode, dataFolder, timeout, host, corsOrigins, rateLimitWindow, rateLimitMaxatm: enabled, endpoint, token, accountId, cache settings, retry settingsai: Comprehensive coverage for 20+ AI/LLM providers (OpenAI, Anthropic, Google, Azure, etc.)vectordb: Pinecone, Weaviate, Qdrant, Milvus, Chroma, Supabase, ElasticSearchdatabase: MySQL, MongoDB, Redis, SQLite, CockroachDB, DynamoDB, Cassandra, Neo4jdataTier: mode (xronox/nx-mongo), engine, xronox settings, nxMongo settingsstorage: S3-compatible storage with full aliasing (S3_/SPACE_/STORAGE_)messaging: RabbitMQ, Kafka, SQS, Pub/Sub, NATSobservability: Prometheus, Grafana, DataDog, New Relic, Sentry, OpenTelemetrylogging: level, format, toFile, filePath, toUnified, debugNamespace, maxFiles, maxSize, compressemail: SendGrid, Mailgun, AWS SES, SMTPpayment: Stripe, PayPal, Squareauth: Auth0, Okta, Clerk, Supabase Authsearch: Algolia, MeiliSearch, Typesensecdn: Cloudflare, Cloudinary, ImageKitanalytics: Google Analytics, Mixpanel, Segment, PostHogfeatureFlags: LaunchDarkly, Flagsmithdeployment: Vercel, Netlify, Docker Hub
Features:
- Default Config Map: Common patterns pre-configured with ENV tokens
- Automatic Addition: All
ALL_UPPERCASEenv vars not in default config are added as camelCase at root - JSON Parsing: JSON-like env vars are automatically parsed
- Beautified Output: Config is sorted with default sections first, then alphabetically
- Non-strict by Default: Missing optional vars don't throw errors
Options:
autoLoadConfig({
dotenvPath: '.env', // .env file path (default: '.env')
includeAllEnvVars: true, // Include additional env vars (default: true)
beautify: true, // Sort keys nicely (default: true)
verbose: false, // Log resolved vars (default: false)
heuristicJsonParsing: true, // Auto-parse JSON (default: true)
sections: ['DATABASE', 'AI'], // Optional: only load these .env sections
groups: ['database.mongodb', 'ai.openai'] // Optional: only load these groups from DEFAULT_CONFIG_MAP
});Example:
// .env file
API_PORT=8080
MONGO_URI=mongodb://localhost:27017/mydb
LOG_LEVEL=debug
DATATIER_MODE=nx-mongo
XRONOX_ENABLED=false
NX_MONGO_ENABLED=true
CUSTOM_VAR=custom-value
JSON_CONFIG={"key":"value"}
// Auto-load config
const config = autoLoadConfig();
// Result structure:
// {
// api: { port: 8080, ... },
// database: { mongodb: { uri: 'mongodb://...', ... }, ... },
// dataTier: { mode: 'nx-mongo', nxMongo: { enabled: true, ... }, ... },
// logging: { level: 'debug', ... },
// customVar: 'custom-value',
// jsonConfig: { key: 'value' }
// }4. Prefix/Suffix Support
nxconfig provides flexible environment variable resolution with prefix and suffix support for multi-tenant and environment-specific configurations:
// All AWS_* variables
parseConfig(config, { prefix: 'AWS_' });
// Environment-specific variables
parseConfig(config, {
suffix: '_PROD' // Prefers API_KEY_PROD over API_KEY
});
// Combined prefix and suffix
parseConfig(config, {
prefix: 'APP_',
suffix: '_PROD' // Looks for APP_API_KEY_PROD
});Prefix/Suffix Features:
- Priority Resolution: Suffix takes precedence over prefix
- Fallback Chain: ENV_VAR_SUFFIX → ENV_VAR_PREFIX → ENV_VAR
- Multi-Environment Support: Perfect for dev/staging/prod setups
- Tenant Isolation: Use prefixes for multi-tenant applications
5. Environment Variable Inspection
Inspect and analyze environment variables in your .env files with detailed information:
import { getEnvVariables } from 'nx-config2';
// Get variables from default .env file
const defaultVars = getEnvVariables();
// Get variables from specific environment file
const testVars = getEnvVariables('test'); // .env.test
const prodVars = getEnvVariables('prod'); // .env.prod
const dbVars = getEnvVariables('prod.database'); // .env.prod.database
console.log(testVars);
// [
// { varName: 'API_KEY', length: 20, synthesizedValue: 'te***89' },
// { varName: 'DB_HOST', length: 18, synthesizedValue: 'test-db.example.com' },
// { varName: 'PASSWORD', length: 25, synthesizedValue: 'su***23' }
// ]Environment Variable Inspection Features:
- Variable Discovery: List all variables in any .env file
- Sensitive Data Masking: Automatically mask passwords, keys, and tokens
- Length Information: Get original value length for validation
- Multi-Environment Support: Works with any environment file path
- Safe Inspection: Sensitive fields are automatically masked
- TypeScript Support: Full type definitions for variable information
🔥 Multi-Config Features
nxconfig provides powerful multi-configuration management with intelligent merging, inheritance, and flexible source handling:
Smart Configuration Merging
Merge multiple configuration sources with intelligent conflict resolution:
import { parseMultiConfig } from 'nx-config2';
// Merge multiple configs into one
const result = parseMultiConfig({
sources: ['./base.json', './production.json', './overrides.json'],
mergeStrategy: 'deep', // 'deep' | 'shallow' | 'override' | 'append'
priority: 'last', // 'first' | 'last'
verbose: true
});
console.log(result.config); // Deeply merged configurationSmart Merging Features:
- Conflict Resolution: Intelligent handling of overlapping keys
- Type Preservation: Maintains data types during merging
- Array Handling: Smart array concatenation and deduplication
- Nested Merging: Deep recursive object merging
- Error Recovery: Graceful handling of merge conflicts
Named Configuration Access
Keep configurations separate but accessible by name for multi-environment setups:
// Keep configs separate but accessible by name
const result = parseMultiConfig({
sources: ['./prod.json', './staging.json', './dev.json'],
keepSeparate: true,
names: ['production', 'staging', 'development']
});
console.log(result.configs.production); // Production config
console.log(result.configs.staging); // Staging config
console.log(result.configs.development); // Development configNamed Access Features:
- Environment Isolation: Keep configs completely separate
- Dynamic Selection: Choose config at runtime based on environment
- Memory Efficient: Only load needed configurations
- Type Safety: Full TypeScript support for named configs
Configuration Inheritance
Build complex configuration hierarchies with base configs and overrides:
// Load base config first, then layer sources
const result = parseMultiConfig({
extends: './base-config.json', // Loaded first
sources: ['./env-specific.json'],
mergeStrategy: 'deep'
});Inheritance Features:
- Base Configuration: Define common settings once
- Layered Overrides: Environment-specific customizations
- Inheritance Chains: Support for multiple levels of inheritance
- Override Protection: Prevent accidental base config modification
Merge Strategies
Choose the right merging strategy for your use case:
// Deep merge (recursive object merging, array concatenation)
mergeStrategy: 'deep' // Best for complex nested configs
// Shallow merge (Object.assign style)
mergeStrategy: 'shallow' // Fast, simple merging
// Override (last source wins completely)
mergeStrategy: 'override' // Complete replacement
// Append (array-focused merging)
mergeStrategy: 'append' // Array concatenation with deduplicationMerge Strategy Details:
- Deep: Recursively merges objects, concatenates arrays, preserves structure
- Shallow: Fast Object.assign-style merging, arrays are replaced
- Override: Last source completely replaces previous sources
- Append: Array-focused merging with intelligent deduplication
🛠️ Advanced Features
Schema Validation (Convict-inspired)
nxconfig provides comprehensive schema validation with detailed error reporting and custom validators:
const result = initConfig(config, {
schema: {
port: {
type: 'port',
required: true,
doc: 'Server port number',
env: 'PORT',
arg: 'port', // --port from command line
default: 3000,
min: 1000,
max: 9999
},
apiKey: {
type: 'string',
required: true,
sensitive: true, // Masks in logs
nullable: false,
format: (val) => val.length >= 32 // Custom validator
},
environment: {
type: 'string',
enum: ['development', 'staging', 'production'],
default: 'development'
},
timeout: {
type: 'duration',
doc: 'Request timeout',
default: '30s'
}
}
});Schema Validation Features:
- Type Validation: Automatic type checking with detailed error messages
- Range Validation: Min/max values for numeric types
- Enum Constraints: Restrict values to predefined options
- Custom Validators: Define your own validation functions
- Required Fields: Enforce mandatory configuration values
- Sensitive Data: Automatic masking of sensitive fields in logs
- Documentation: Built-in field documentation support
- Command-line Integration: Map schema fields to CLI arguments
Hierarchical Configuration (nconf-inspired)
Build complex configuration hierarchies with priority-based value resolution:
import { ConfigurationHierarchy } from 'nx-config2';
const config = new ConfigurationHierarchy();
// Priority: overrides > env > file > defaults
config.set('database:host', '127.0.0.1');
config.set('database:port', 5432);
console.log(config.get('database:host')); // '127.0.0.1'
console.log(config.toObject());Hierarchical Features:
- Priority Resolution: Clear precedence order for value sources
- Nested Key Access: Use colon-separated keys for deep access
- Dynamic Updates: Modify configuration at runtime
- Memory Management: Efficient storage and retrieval
- Type Safety: Full TypeScript support for hierarchical access
Command-line Arguments
Parse command-line arguments directly into your configuration:
// node app.js --port=8080 --debug=true
const result = parseConfig(config, {
commandLineArgs: true
});CLI Integration Features:
- Automatic Parsing: Parse
--flag=valueand--flagpatterns - Type Coercion: Apply type conversion to CLI values
- Priority Override: CLI args override environment variables
- Validation: Validate CLI arguments against schema
- Help Generation: Auto-generate help text from schema
Auto-Documentation Generation
Generate comprehensive documentation for your configuration automatically:
const result = initConfig(config, {
generateDocs: true,
docsPath: './ENV_VARS.md',
descriptions: {
API_KEY: 'Authentication key for external services',
DB_HOST: 'Database server hostname',
PORT: 'HTTP server port (1000-65535)'
},
schema: {
PORT: {
type: 'port',
required: true,
doc: 'Server listening port'
}
}
});
// Generates beautiful markdown documentation!Documentation Features:
- Markdown Generation: Professional documentation format
- Variable Tables: Organized tables with types, defaults, descriptions
- Usage Examples: Auto-generated usage examples
- Sensitive Data: Automatic masking of sensitive fields
- Schema Integration: Include validation rules in documentation
Output:
# Configuration Documentation
## Environment Variables
| Variable | Type | Required | Default | Description | Sensitive |
|----------|------|----------|---------|-------------|-----------|
| `API_KEY` | `string` | ✅ Yes | - | Authentication key... | 🔒 Yes |
| `PORT` | `port` | ✅ Yes | `3000` | Server listening port | ❌ No |
## Usage Example
```bash
export API_KEY="your-api-key"
export PORT="8080"
### Directory Auto-Creation
Automatically create missing directories for path-based configurations:
```typescript
const config = {
uploadDir: 'ENV.UPLOAD_PATH',
cacheDir: 'ENV.CACHE_PATH',
logDir: 'ENV.LOG_PATH'
};
parseConfig(config, {
createDirectories: true // Creates missing directories
});Directory Features:
- Automatic Creation: Creates missing directories recursively
- Permission Handling: Respects existing permissions
- Error Recovery: Graceful handling of creation failures
- Path Validation: Validates paths before creation
- Verbose Logging: Logs directory creation activities
Path Validation
Validate file and directory existence with comprehensive error reporting:
schema: {
configFile: {
type: 'string',
isFile: true, // Validates file exists
required: true
},
dataDir: {
type: 'string',
isDirectory: true, // Validates directory exists
required: true
}
}Path Validation Features:
- File Existence: Validate files exist and are readable
- Directory Validation: Check directory existence and permissions
- Path Resolution: Handle relative and absolute paths
- Error Details: Detailed error messages for missing paths
- Schema Integration: Works seamlessly with validation schemas
Secret Masking
Automatically detect and mask sensitive data in configurations:
import { maskSecrets } from 'nx-config2';
const config = {
api_key: 'secret123456',
password: 'mypassword',
username: 'john'
};
console.log(maskSecrets(config));
// {
// api_key: 'se***56',
// password: 'my***rd',
// username: 'john'
// }Secret Masking Features:
- Automatic Detection: Identifies sensitive fields by name patterns
- Smart Masking: Preserves first/last characters for readability
- Schema Integration: Use schema to mark sensitive fields
- Custom Patterns: Define your own sensitive field patterns
- Log Safety: Safe for logging and debugging
Hot Reload
Watch configuration files for changes and automatically reload:
import { watchConfig } from 'nx-config2';
const watcher = watchConfig('./config.json', {
interval: 2000,
onChange: (newConfig) => {
console.log('⚡ Config reloaded:', newConfig);
},
onError: (error) => {
console.error('❌ Error:', error);
}
});
// Stop watching later
watcher.stop();Hot Reload Features:
- File Watching: Monitor configuration files for changes
- Automatic Reload: Seamlessly reload on file changes
- Error Handling: Graceful error recovery and reporting
- Performance: Efficient file change detection
- Memory Management: Proper cleanup and resource management
Convict-style API
Use a familiar convict-style API for configuration management:
import { createConfig } from 'nx-config2';
const config = createConfig({
env: {
doc: 'The application environment',
format: ['production', 'development', 'test'],
default: 'development',
env: 'NODE_ENV'
},
port: {
doc: 'The port to bind',
format: 'port',
default: 8080,
env: 'PORT',
arg: 'port'
}
});
config.validate();
console.log(config.get('port'));
console.log(config.getProperties());Convict-style Features:
- Familiar API: Drop-in replacement for convict users
- Schema Definition: Define configuration schema declaratively
- Validation: Built-in validation with detailed error messages
- Documentation: Automatic documentation generation
- Type Safety: Full TypeScript support
- Environment Integration: Seamless environment variable handling
Environment Variable Inspection
Inspect and analyze environment variables in your .env files with detailed information:
import { getEnvVariables } from 'nx-config2';
// Get variables from default .env file
const defaultVars = getEnvVariables();
// Get variables from specific environment file
const testVars = getEnvVariables('test'); // .env.test
const prodVars = getEnvVariables('prod'); // .env.prod
const dbVars = getEnvVariables('prod.database'); // .env.prod.database
console.log(testVars);
// [
// { varName: 'API_KEY', length: 20, synthesizedValue: 'te***89' },
// { varName: 'DB_HOST', length: 18, synthesizedValue: 'test-db.example.com' },
// { varName: 'PASSWORD', length: 25, synthesizedValue: 'su***23' }
// ]Environment Variable Inspection Features:
- Variable Discovery: List all variables in any .env file
- Sensitive Data Masking: Automatically mask passwords, keys, and tokens
- Length Information: Get original value length for validation
- Multi-Environment Support: Works with any environment file path
- Safe Inspection: Sensitive fields are automatically masked
- TypeScript Support: Full type definitions for variable information
📖 Complete Examples
Environment Variable Inspection (NEW!)
import { getEnvVariables, parseConfig } from 'nx-config2';
// Inspect variables from different environment files
const defaultVars = getEnvVariables(); // .env
const testVars = getEnvVariables('test'); // .env.test
const prodVars = getEnvVariables('prod'); // .env.prod
const dbVars = getEnvVariables('prod.database'); // .env.prod.database
console.log('Default environment variables:', defaultVars.length);
console.log('Test environment variables:', testVars.length);
console.log('Production environment variables:', prodVars.length);
console.log('Database environment variables:', dbVars.length);
// Display variable information with sensitive data masking
testVars.forEach(variable => {
console.log(`${variable.varName}: ${variable.synthesizedValue} (length: ${variable.length})`);
});
// Use in configuration validation
const config = parseConfig({
api: {
key: 'ENV.TEST.API_KEY',
host: 'ENV.TEST.API_HOST'
}
});
// Verify all required variables exist
const requiredVars = ['API_KEY', 'API_HOST'];
const missingVars = requiredVars.filter(varName =>
!testVars.some(v => v.varName === varName)
);
if (missingVars.length > 0) {
console.error('Missing required variables:', missingVars);
}Cloud-Native Application
import { initConfig } from 'nx-config2';
const config = initConfig({
service: {
name: 'ENV.SERVICE_NAME',
version: 'ENV.APP_VERSION',
port: 'ENV.PORT:port||8080',
host: 'ENV.HOST||0.0.0.0'
},
database: {
url: 'ENV.DATABASE_URL',
poolSize: 'ENV.DB_POOL_SIZE:nat||10',
ssl: 'ENV.DB_SSL:boolean||true'
},
redis: {
url: 'ENV.REDIS_URL',
ttl: 'ENV.REDIS_TTL:duration||1h'
},
logging: {
level: 'ENV.LOG_LEVEL||info',
pretty: 'ENV.LOG_PRETTY:boolean||false'
}
}, {
prefix: 'APP_',
requiredVars: ['SERVICE_NAME', 'DATABASE_URL'],
dotenvPath: '.env',
generateDocs: true,
docsPath: './docs/ENV_VARS.md',
schema: {
port: {
type: 'port',
min: 1000,
max: 65535,
doc: 'HTTP server port'
}
},
verbose: true
});
console.log('✅ Configuration loaded successfully!');Multi-Environment Setup
const env = process.env.NODE_ENV || 'development';
const config = initConfig('./config.json', {
dotenvPath: `.env.${env}`,
suffix: `_${env.toUpperCase()}`,
overrides: {
environment: env
},
defaults: {
LOG_LEVEL: 'info',
PORT: '3000'
}
});Multi-Environment File Setup (NEW!)
// .env.test file
API_KEY=test-api-key-123
DB_HOST=test-db.example.com
DB_PORT=5432
// .env.prod.database file
HOST=prod-db.example.com
PORT=5432
SSL=true
// .env.staging.api file
KEY=staging-api-key-456
TIMEOUT=30s
const config = {
// Simple pattern
app: {
name: 'ENV.APP_NAME||my-app'
},
// Test environment
test: {
apiKey: 'ENV.TEST.API_KEY',
dbHost: 'ENV.TEST.DB_HOST',
dbPort: 'ENV.TEST.DB_PORT:port'
},
// Production database
production: {
database: {
host: 'ENV.PROD.DATABASE.HOST',
port: 'ENV.PROD.DATABASE.PORT:port',
ssl: 'ENV.PROD.DATABASE.SSL:boolean'
}
},
// Staging API
staging: {
api: {
key: 'ENV.STAGING.API.KEY',
timeout: 'ENV.STAGING.API.TIMEOUT:duration'
}
}
};
const result = initConfig(config, { verbose: true });AWS Configuration with Prefix
process.env.AWS_ACCESS_KEY_ID = 'AKIA...';
process.env.AWS_SECRET_ACCESS_KEY = 'secret...';
process.env.AWS_REGION = 'us-east-1';
process.env.AWS_LOG_DIR = './aws-logs';
const awsConfig = initConfig({
accessKeyId: 'ENV.ACCESS_KEY_ID',
secretAccessKey: 'ENV.SECRET_ACCESS_KEY',
region: 'ENV.REGION',
logDir: 'ENV.LOG_DIR'
}, {
prefix: 'AWS_',
createDirectories: true,
schema: {
logDir: {
type: 'string',
isDirectory: true
}
}
});Multi-Config Production Setup
import { parseMultiConfig } from 'nx-config2';
// Production environment with multiple config sources
const result = parseMultiConfig({
sources: [
'./configs/base.json', // Base configuration
'./configs/database.json', // Database settings
'./configs/redis.json', // Redis settings
'./configs/production.json', // Production overrides
'./configs/secrets.json' // Secret values
],
mergeStrategy: 'deep',
priority: 'last',
dotenvPath: '.env.production',
prefix: 'APP_',
verbose: true,
schema: {
port: {
type: 'port',
required: true,
doc: 'HTTP server port'
}
}
});
console.log('🔧 Merged configuration:', result.config);
console.log('📊 Resolved variables:', result.resolvedVars);Separate Environment Configs
// Load all environment configs separately
const envConfigs = parseMultiConfig({
sources: [
'./configs/development.json',
'./configs/staging.json',
'./configs/production.json'
],
keepSeparate: true,
names: ['development', 'staging', 'production'],
dotenvPath: '.env',
verbose: true
});
// Use the appropriate config based on NODE_ENV
const env = process.env.NODE_ENV || 'development';
const currentConfig = envConfigs.configs[env];
console.log(`🌍 Using ${env} configuration:`, currentConfig);🔧 API Reference
Core Functions
parseConfig<T>(config, options?)
Parse a configuration object and resolve ENV tokens.
Options:
strict: Throw on missing vars (default:true)verbose: Log resolved variables (default:false)dotenvPath: Load .env fileprefix: Prepend to all ENV var namessuffix: Append to all ENV var names (env-specific)defaults: Default values for ENV varstransform: Custom transformerscreateDirectories: Auto-create directoriescommandLineArgs: Parse from process.argvenvSeparator: For nested keys (default:__)heuristicJsonParsing: Auto-detect and parse JSON-like strings (default:true)lenientJson: Return original string on JSON parse failure instead of throwing (default:false)
parseMultiConfig<T>(options) (NEW!)
Smart multi-config handling with merge strategies.
Options:
sources: Array of config sourcesmergeStrategy: How to merge configs ('deep' | 'shallow' | 'override' | 'append')keepSeparate: Keep configs separate (named access)names: Names for each config (if keepSeparate)extends: Base config to extend frompriority: Which source has priority ('first' | 'last')- All
parseConfigoptions
initConfig<T>(config, options?)
One-call initialization with validation.
Additional Options:
requiredVars: Required environment variablesvalidateOnInit: Run validation (default:true)throwOnMissing: Throw if vars missing (default:true)schema: Schema validationgenerateDocs: Auto-generate docsdocsPath: Where to save docsdescriptions: Variable descriptionsoverrides: Highest priority valuesstores: Multiple configuration stores
ERC Compliance Options (NEW!):
ercMode: Enable ERC compliance mode (default:false)componentName: Component name for ERC manifest (required ifercModeorgenerateManifestis true)componentVersion: Component version stringercVersion: ERC standard version (default:'1.1.0')ercDependencies: Array of ERC-compliant dependency package namesgenerateManifest: Generateerc-manifest.json(default:false)manifestPath: Path to save ERC manifest (default:'./erc-manifest.json')generateEnvExample: Generate.env.examplefile (default:false)envExamplePath: Path to save.env.example(default:'./.env.example')validateERC: Validate ERC compliance (default:false)updateReadme: Update README with ERC badge (default:false)readmePath: Path to README file (default:'./README.md')
remoteConfig<T>(options?) (NEW!)
Initialize configuration from a remote JSON source using nx-remote-json. Fetches configuration from disk, S3-compatible storage, or MongoDB, then processes it through the standard initConfig pipeline.
Options:
remoteJsonConfig: Configuration for the remote JSON clientmode: Backend mode ("disk","storage", or"database") - supportsENV.VARIABLEpatternjsonRouter: Router name for the remote config - supportsENV.VARIABLEpatternjsonKey: Key name for the remote config - supportsENV.VARIABLEpattern- All
initConfigoptions (exceptstores)
Example:
import { remoteConfig } from 'nx-config2';
// Import your remote JSON client implementation
const result = await remoteConfig({
remoteJsonConfig: {
disk: {
rootLocation: "/data/configs",
mapping: [{ jsonRouter: "app", folder: "app-configs" }]
}
},
mode: "disk",
jsonRouter: "app",
jsonKey: "production"
});
console.log(result.config);Using Environment Variables:
// Set environment variables
process.env.CONFIG_MODE = "storage";
process.env.CONFIG_ROUTER = "settings";
process.env.CONFIG_KEY = "user-123";
const result = await remoteConfig({
remoteJsonConfig: {
storage: {
region: "us-east-1",
endpoint: "https://s3.amazonaws.com",
bucket: "my-bucket",
accessKey: process.env.AWS_ACCESS_KEY!,
secretKey: process.env.AWS_SECRET_KEY!,
mapping: [{ jsonRouter: "settings", folder: "settings" }]
}
},
mode: "ENV.CONFIG_MODE", // Resolved from process.env.CONFIG_MODE
jsonRouter: "ENV.CONFIG_ROUTER", // Resolved from process.env.CONFIG_ROUTER
jsonKey: "ENV.CONFIG_KEY" // Resolved from process.env.CONFIG_KEY
});verify(variableNames)
Validate environment variables are set.
watchConfig<T>(configPath, options?)
Watch a config file for changes.
createConfig<T>(schema)
Create a convict-style config with schema.
autoLoadConfig<T>(options?) (NEW!)
Automatically load configuration from environment variables using a default config map plus any additional env vars.
Options:
dotenvPath: Path to .env file (default:.env)includeAllEnvVars: Include all env vars not in default config (default:true)beautify: Sort and format output nicely (default:true)enableSharedEnv: Enable shared .env file support (default:true)sharedEnvRequired: Require shared files to exist (default:true)sections: Optional array of section names to load from.env(e.g.['DATABASE', 'AI'])groups: Optional array of group paths fromDEFAULT_AUTO_CONFIG_MAPto load (e.g.['database.mongodb', 'ai.openai'])- All
parseConfigoptions
Sections in .env:
Sections are defined using headers like [DATABASE] and [AI]:
[DATABASE]
MONGO_URI=mongodb://...
MONGO_LOGS_DB=logs-db
[AI]
OPENAI_API_KEY=sk-...
GROK_API_KEY=...Then load only specific sections:
const config = autoLoadConfig({
sections: ['DATABASE', 'AI']
});Groups in DEFAULT_AUTO_CONFIG_MAP:
Groups correspond to dot-notation paths in the default config map (e.g. database.mongodb, ai.openai, contentRegistry.github):
const config = autoLoadConfig({
groups: ['database.mongodb', 'ai.openai', 'contentRegistry.github']
});Utility Functions
normalizeMongoUri(uri)
Normalize MongoDB connection URIs by adding the mongodb:// prefix if missing.
Parameters:
uri(string | undefined): MongoDB connection URI
Returns: string | undefined - Normalized URI with protocol prefix
Example:
import { normalizeMongoUri } from 'nx-config2';
const uri = normalizeMongoUri('localhost:27017/mydb');
// Returns: 'mongodb://localhost:27017/mydb'
// Already has prefix - no change
const uri2 = normalizeMongoUri('mongodb://localhost:27017/mydb');
// Returns: 'mongodb://localhost:27017/mydb'
// Handles undefined gracefully
const uri3 = normalizeMongoUri(undefined);
// Returns: undefinedUse Case: Downstream packages can use this utility to ensure MongoDB URIs are properly formatted before database connection:
import { normalizeMongoUri } from 'nx-config2';
// In ActivityTracker or other MongoDB client initialization
const mongoUri = normalizeMongoUri(config.MONGO_URI);
await mongoose.connect(mongoUri);maskSecrets(config, path?, schema?)
Mask sensitive fields in configuration.
extractEnvTokens(config)
Extract all ENV tokens from a configuration.
generateDocumentation(config, resolvedVars, descriptions?, schema?)
Generate markdown documentation.
validateRequiredEnvVars(variableNames)
Validate required environment variables.
🔐 ERC (Environment Requirements Contract) Compliance
nx-config2 now includes built-in support for ERC compliance, making it easy to create ERC-compliant components with automatic manifest generation, dependency scanning, and .env.example generation.
What is ERC?
ERC (Environment Requirements Contract) is a standard for documenting and managing environment variable requirements across components and their dependencies. It ensures:
- ✅ Transparent Requirements: All environment variables are documented
- ✅ Dependency Awareness: Transitive requirements from dependencies are automatically merged
- ✅ Zero-Config Setup:
.env.examplefiles are generated automatically - ✅ Validation: ERC compliance can be verified at build/runtime
- ✅ CI/CD Integration:
erc-verifycommand for pipelines
Quick Start with ERC
Enable ERC mode with just a few options:
import { initConfig } from 'nx-config2';
export class AIGateway {
constructor(config = {}) {
this.config = initConfig({
github: {
token: 'ENV.GITHUB_TOKEN',
apiUrl: 'ENV.GITHUB_API_URL||https://api.github.com'
},
api: {
timeout: 'ENV.GATEWAY_TIMEOUT:duration||30s'
}
}, {
ercMode: true, // Enable ERC compliance mode
componentName: 'ai-gateway',
componentVersion: '1.1.0',
generateManifest: true, // Generates erc-manifest.json
generateEnvExample: true, // Generates .env.example
validateERC: true,
updateReadme: true // Adds ERC badge to README
}).config;
}
}Generated Files
erc-manifest.json
{
"component": "ai-gateway",
"version": "1.1.0",
"ercCompliant": true,
"ercVersion": "1.1.0",
"requirements": {
"required": [
{
"variable": "GITHUB_TOKEN",
"type": "string",
"sensitive": true,
"description": "GitHub API authentication token"
}
],
"optional": [
{
"variable": "GITHUB_API_URL",
"type": "url",
"default": "https://api.github.com",
"description": "Override default GitHub API endpoint"
},
{
"variable": "GATEWAY_TIMEOUT",
"type": "duration",
"default": "30s",
"description": "Request timeout"
}
]
},
"dependencies": []
}.env.example
# ============================================
# ai-gateway Configuration
# ============================================
# [REQUIRED]
GITHUB_TOKEN=your_secret_here
# Purpose: GitHub API authentication token
# [OPTIONAL]
# GITHUB_API_URL=https://api.github.com
# Purpose: Override default GitHub API endpoint
# Default: https://api.github.com
# GATEWAY_TIMEOUT=30s
# Purpose: Request timeout
# Default: 30sTransitive Requirement Merging
When your component depends on ERC-compliant packages, their requirements are automatically merged:
import { initConfig } from 'nx-config2';
export class AISkills {
constructor(config = {}) {
this.config = initConfig({
apiKey: 'ENV.AI_SKILLS_API_KEY',
timeout: 'ENV.AI_SKILLS_TIMEOUT:duration||60s'
}, {
ercMode: true,
componentName: 'ai-skills',
ercDependencies: [
'@athenices/ai-gateway', // Reads its erc-manifest.json
'@xeonoces/cloud-storage'
],
generateManifest: true,
generateEnvExample: true
}).config;
}
}The generated .env.example will include:
- Your component's requirements
- All required variables from
@athenices/ai-gateway - All required variables from
@xeonoces/cloud-storage - All optional variables with their defaults
ERC Functions
generateERCManifest(config, options)
Generate an ERC manifest from a configuration object.
import { generateERCManifest } from 'nx-config2';
const manifest = generateERCManifest(config, {
componentName: 'my-component',
componentVersion: '1.0.0',
ercVersion: '1.1.0',
schema: mySchema,
descriptions: myDescriptions
});mergeERCRequirements(ownRequirements, dependencies, projectRoot?)
Merge requirements from ERC-compliant dependencies.
import { mergeERCRequirements } from 'nx-config2';
const merged = mergeERCRequirements(
{ required: [...], optional: [...] },
['@athenices/ai-gateway', '@xeonoces/cloud-storage']
);generateEnvExample(requirements, options)
Generate a .env.example file from ERC requirements.
import { generateEnvExample } from 'nx-config2';
const envExample = generateEnvExample(requirements, {
componentName: 'my-component',
dependencyManifests: dependencyManifestsMap
});validateERC(manifestPath?, projectRoot?)
Validate ERC compliance of a project.
import { validateERC } from 'nx-config2';
const result = validateERC('./erc-manifest.json');
if (!result.valid) {
console.error('ERC validation failed:', result.errors);
}CLI: erc-verify
Verify ERC compliance from the command line:
# Basic verification
npx nx-config2 erc-verify
# With custom manifest path
npx nx-config2 erc-verify --manifest ./custom-manifest.json
# Strict mode (exit with error code on failure)
npx nx-config2 erc-verify --strict
# Verbose output
npx nx-config2 erc-verify --verboseERC Badge
When updateReadme: true is set, nx-config2 automatically adds an ERC badge to your README:
Benefits
✅ Zero Config Implementation: Components become ERC-compliant with 3 lines of code
✅ Automatic Documentation: .env.example generated automatically
✅ Transitive Requirements: Dependencies auto-merged
✅ Validation Built-in: ERC compliance checked at build/runtime
✅ CI/CD Integration: erc-verify command for pipelines
✅ Type Safety: Full TypeScript support
✅ Migration Path: Easy upgrade for existing components
🎨 TypeScript Support & IntelliSense
Full TypeScript support with comprehensive IntelliSense for autoLoadConfig():
Default Config Types
The DefaultConfig interface provides full IntelliSense for all default configuration sections:
import { autoLoadConfig, DefaultConfig } from 'nx-config2';
// Explicit typing for best IntelliSense support
const config: DefaultConfig = autoLoadConfig();
// Full IntelliSense works for all sections:
config.ai?.openai?.apiKey // ✅ OpenAI API key
config.ai?.xai?.apiKey // ✅ Grok/XAI API key
config.database?.mongodb?.uri // ✅ MongoDB URI
config.database?.mongodb?.logsDatabase // ✅ Logs database
config.contentRegistry?.local?.path // ✅ Content registry path
config.logging?.level // ✅ Log level
config.testing?.scopedTextFile // ✅ Test config
config.agent?.id // ✅ Agent ID
// Nested MongoDB role configurations:
config.database?.mongodb?.roles?.runtime?.connectionString
config.database?.mongodb?.roles?.metadata?.database
config.database?.mongodb?.roles?.knowledge?.database
config.database?.mongodb?.roles?.memory?.databaseGeneric Type Parameter
You can also use the generic type parameter:
const config = autoLoadConfig<DefaultConfig>();
// Same IntelliSense supportExtending Default Config
Extend DefaultConfig to add your own custom properties:
import { DefaultConfig } from 'nx-config2';
interface MyAppConfig extends DefaultConfig {
customField?: {
myValue?: string;
};
}
const config = autoLoadConfig<MyAppConfig>({
includeAllEnvVars: true // Allows additional properties
});Legacy Type Support
For initConfig() and other functions, you can still use custom interfaces:
interface AppConfig {
database: {
host: string;
port: number;
};
api: {
key: string;
timeout: number;
};
}
const result = initConfig<AppConfig>(config);
// result.config is typed as AppConfig