A unified configuration library combining Links Notation Environment (lino-env), yargs, and environment variables with a clear priority chain.
lino-arguments provides a unified configuration system that automatically loads configuration from multiple sources with a clear priority chain:
- CLI arguments - Highest priority (manually entered options)
- getenv defaults - Environment variable lookups with fallbacks
- --configuration flag - Dynamic .lenv file path via CLI
.lenvfile - Local environment overrides using Links Notation.envfile - Base configuration (DEPRECATED, use .lenv instead)
npm install lino-argumentsimport { makeConfig } from 'lino-arguments';
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs.option('port', { default: getenv('PORT', 3000) }),
});That's it! This simple configuration:
- ✅ Loads from
.lenvfile automatically - ✅ Reads
PORTenvironment variable with fallback to 3000 - ✅ Accepts
--portCLI argument with highest priority - ✅ Supports
--configurationto specify custom .lenv file path - ✅ Returns clean object with camelCase keys
import { makeConfig } from 'lino-arguments';
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs
.option('port', {
type: 'number',
default: getenv('PORT', 3000),
describe: 'Server port'
})
.option('api-key', {
type: 'string',
default: getenv('API_KEY', ''),
describe: 'API authentication key'
})
.option('verbose', {
type: 'boolean',
default: false,
describe: 'Enable verbose logging'
})
});
console.log(config);
// { port: 3000, apiKey: '...', verbose: false }
## API Reference
### `makeConfig(config)` (Primary API)
The main function for creating unified configuration from multiple sources.
**Parameters:**
- `config` (Object): Configuration object
- `yargs` (Function): Required. Yargs configuration function receiving `({ yargs, getenv })`
- `lenv` (Object): Optional. .lenv file configuration
- `enabled` (boolean): Enable .lenv loading (default: `true`)
- `path` (string): Path to .lenv file (default: `'.lenv'`)
- `override` (boolean): Override existing env vars (default: `true`)
- `env` (Object): Optional. dotenvx/.env configuration (DEPRECATED)
- `enabled` (boolean): Enable .env loading (default: `false`)
- `quiet` (boolean): Suppress deprecation warnings (default: `true`)
- `getenv` (Object): Optional. getenv helper configuration
- `enabled` (boolean): Enable getenv helper (default: `true`)
- `argv` (string[]): Optional. Custom argv to parse (default: `process.argv`)
**Returns:** `Object` - Parsed configuration with camelCase keys
**Example:**
```javascript
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs
.option('port', { type: 'number', default: getenv('PORT', 3000) })
.option('api-key', { type: 'string', default: getenv('API_KEY', '') })
.option('verbose', { type: 'boolean', default: false })
});Smart environment variable lookup with type preservation and case conversion.
Built on getenv: This function uses the official getenv npm package internally for robust type casting and validation, enhanced with case-insensitive lookup across multiple naming conventions.
Parameters:
name(string): Environment variable name (any case format)defaultValue(any): Default value if not found
Returns: Same type as defaultValue
Example:
// All these work and return the same value:
getenv('API_KEY', ''); // UPPER_CASE
getenv('apiKey', ''); // camelCase
getenv('api-key', ''); // kebab-case
getenv('api_key', ''); // snake_case
// Type preservation (powered by getenv package):
getenv('PORT', 3000); // Returns number (uses getenv.int())
getenv('DEBUG', false); // Returns boolean (uses getenv.boolish())
getenv('API_KEY', ''); // Returns string (uses getenv.string())Utility functions for converting between naming conventions:
toUpperCase(str)- Convert to UPPER_CASE (environment variables)toCamelCase(str)- Convert to camelCase (config object keys)toKebabCase(str)- Convert to kebab-case (CLI options)toSnakeCase(str)- Convert to snake_casetoPascalCase(str)- Convert to PascalCase
Example:
import { toUpperCase, toCamelCase, toKebabCase } from 'lino-arguments';
toUpperCase('apiKey'); // 'API_KEY'
toCamelCase('api-key'); // 'apiKey'
toKebabCase('apiKey'); // 'api-key'These functions are available for advanced use cases but makeConfig() is recommended for most applications:
Apply .lenv file to process.env.
.lenv files instead of .env files.
The .lenv file uses Links Notation format with : (colon-space) separator:
# Database configuration
DATABASE_URL: postgresql://localhost:5432/myapp
DATABASE_POOL_SIZE: 10
# API Keys
API_KEY: your_api_key_here
SECRET_KEY: your_secret_key_here
# Application settings
APP_NAME: My Application
APP_PORT: 3000
makeConfig() automatically loads and merges configuration from multiple sources with a clear priority chain:
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs.option('port', { default: getenv('PORT', 3000) }),
});Priority order (highest to lowest):
- CLI arguments:
--port 8080 - getenv defaults:
process.env.PORT - --configuration flag:
--configuration custom.lenv - .lenv file: Local environment overrides
- .env file: Base configuration (DEPRECATED)
The getenv() helper automatically searches for environment variables in all common case formats:
// If process.env.API_KEY = 'secret123'
getenv('API_KEY', ''); // ✅ Found
getenv('apiKey', ''); // ✅ Found (converted to API_KEY)
getenv('api-key', ''); // ✅ Found (converted to API_KEY)
getenv('api_key', ''); // ✅ Found (converted to API_KEY)CLI options in kebab-case are automatically converted to camelCase in the result:
$ node app.js --api-key mykey --max-connections 100const config = makeConfig({
yargs: ({ yargs }) =>
yargs
.option('api-key', { type: 'string' })
.option('max-connections', { type: 'number' }),
});
console.log(config);
// { apiKey: 'mykey', maxConnections: 100 }Use --configuration (or -c) to specify a different .lenv file at runtime:
$ node app.js --configuration production.lenvHere's a complete example based on the hive-mind pattern:
import { makeConfig } from 'lino-arguments';
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs
.option('port', {
type: 'number',
default: getenv('PORT', 3000),
describe: 'Server port',
})
.option('telegram-token', {
type: 'string',
default: getenv('TELEGRAM_TOKEN', ''),
describe: 'Telegram bot token',
})
.option('api-key', {
type: 'string',
default: getenv('API_KEY', ''),
describe: 'API authentication key',
})
.option('verbose', {
type: 'boolean',
default: false,
describe: 'Enable verbose logging',
})
.option('debug', {
type: 'boolean',
default: false,
describe: 'Enable debug mode',
}),
});
// Start your application
startServer(config);Create a .lenv file for local development:
PORT: 3000
TELEGRAM_TOKEN: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
API_KEY: dev_key_12345
Override values via CLI:
$ node app.js --port 8080 --verboseThe library uses test-anywhere for testing across multiple JavaScript runtimes:
# Run tests on Node.js
npm test
# Run tests on Bun
bun test
# Run tests on Deno
deno test --allow-read --allow-write --allow-env# Install dependencies
npm install
# Run tests
npm test
# Run linting
npm run lint
# Check formatting
npm run format:check
# Fix formatting
npm run format
# Check file size limits
npm run check:file-sizeWe use changesets for version management:
# Create a changeset
npm run changeset
# Check changeset status
npm run changeset:status- links-notation - Links Notation parser
- lino-env - .lenv file operations
- test-anywhere - Universal JavaScript testing
- getenv - Environment variable helper with type casting (used internally)
This is free and unencumbered software released into the public domain. See the LICENSE file for details.