@hiscojs/dotenv-updater
v1.0.0
Published
Type-safe .env file parser and updater with formatting preservation, comment handling, and advanced value quoting
Maintainers
Readme
@hiscojs/dotenv-updater
Type-safe .env file parser and updater with formatting preservation, comment handling, and advanced value quoting.
Installation
npm install @hiscojs/dotenv-updaterQuick Start
import { parse, editInString } from '@hiscojs/dotenv-updater';
// Parse .env content
const envContent = `
DATABASE_URL=postgres://localhost
API_KEY="secret-key"
DEBUG=true
`;
const parsed = parse(envContent);
// { DATABASE_URL: 'postgres://localhost', API_KEY: 'secret-key', DEBUG: 'true' }
// Update .env content
const updated = editInString(envContent, {
DATABASE_URL: 'postgres://production',
API_KEY: 'new-secret',
NEW_VAR: 'new-value'
});Features
- Parse .env files: Convert .env file content to JavaScript objects
- Update .env files: Modify .env content while preserving formatting
- Preserve comments: Comments and empty lines are maintained
- Smart quoting: Automatically quotes values based on content (newlines, special chars)
- Remove unused keys: Keys not in the update object are removed
- Handle invalid lines: Gracefully handles lines without
=signs - Type-safe: Full TypeScript support
API Reference
parse(src: string): Record<string, string | undefined>
Parse a .env file content string into a key-value object.
Parameters:
src- The .env file content as a string
Returns:
- An object with environment variable keys and values
Example:
const envContent = `
DATABASE_URL=postgres://localhost
API_KEY="secret-key"
DEBUG=true
`;
const parsed = parse(envContent);
// {
// DATABASE_URL: 'postgres://localhost',
// API_KEY: 'secret-key',
// DEBUG: 'true'
// }editInString(src: string, object: Record<string, string | undefined>): string
Update a .env file content string with new values while preserving formatting, comments, and structure.
Features:
- Preserves comments and empty lines
- Maintains original indentation and spacing
- Removes keys not present in the updates object
- Adds new keys at the end
- Intelligently quotes values based on their content
Parameters:
src- The original .env file contentobject- An object with keys to update/add and their new values
Returns:
- The updated .env file content
Example:
const original = `
# Database configuration
DATABASE_URL=localhost
API_KEY=old-key
UNUSED_KEY=will-be-removed
`;
const updates = {
DATABASE_URL: 'production-db',
API_KEY: 'new-key',
NEW_SETTING: 'value'
};
const result = editInString(original, updates);
// Result:
// # Database configuration
// DATABASE_URL=production-db
// API_KEY=new-key
// NEW_SETTING=valueUsage Examples
Basic Parsing
import { parse } from '@hiscojs/dotenv-updater';
const content = `
PORT=3000
HOST=localhost
DEBUG=true
`;
const env = parse(content);
console.log(env.PORT); // '3000'
console.log(env.HOST); // 'localhost'
console.log(env.DEBUG); // 'true'Updating Environment Variables
import { editInString } from '@hiscojs/dotenv-updater';
const original = `
# Server configuration
PORT=3000
HOST=localhost
# Database
DB_HOST=localhost
DB_PORT=5432
`;
const updates = {
PORT: '8080',
HOST: '0.0.0.0',
DB_HOST: 'production-db.example.com',
DB_PORT: '5432',
NEW_VAR: 'new-value'
};
const result = editInString(original, updates);
console.log(result);
// # Server configuration
// PORT=8080
// HOST=0.0.0.0
//
// # Database
// DB_HOST=production-db.example.com
// DB_PORT=5432
// NEW_VAR=new-valueHandling Quoted Values
The library automatically handles different quoting styles:
import { parse } from '@hiscojs/dotenv-updater';
const content = `
SINGLE='single quoted'
DOUBLE="double quoted"
BACKTICK=\`backtick quoted\`
UNQUOTED=no-quotes
`;
const env = parse(content);
// All values are unquoted in the result:
// {
// SINGLE: 'single quoted',
// DOUBLE: 'double quoted',
// BACKTICK: 'backtick quoted',
// UNQUOTED: 'no-quotes'
// }When updating, values are automatically quoted based on content:
import { editInString } from '@hiscojs/dotenv-updater';
const updates = {
SIMPLE: 'simple-value', // No quotes needed
WITH_QUOTES: 'has "quotes"', // Uses single quotes
WITH_NEWLINE: 'line1\nline2', // Uses backticks
WITH_ALL: 'has \' and " quotes' // Uses backticks with escaping
};
const result = editInString('', updates);
// SIMPLE=simple-value
// WITH_QUOTES='has "quotes"'
// WITH_NEWLINE=`line1
// line2`
// WITH_ALL=`has ' and " quotes`Preserving Comments
import { editInString } from '@hiscojs/dotenv-updater';
const original = `
# Application settings
APP_NAME=myapp
APP_VERSION=1.0.0 # Current version
# Database configuration
DB_HOST=localhost # Development database
`;
const updates = {
APP_NAME: 'myapp',
APP_VERSION: '2.0.0',
DB_HOST: 'production-db'
};
const result = editInString(original, updates);
// Comments are preserved:
// # Application settings
// APP_NAME=myapp
// APP_VERSION=2.0.0 # Current version
//
// # Database configuration
// DB_HOST=production-db # Development databaseRemoving Keys
Keys not present in the updates object are automatically removed:
import { editInString } from '@hiscojs/dotenv-updater';
const original = `
KEEP_ME=value1
REMOVE_ME=value2
ALSO_KEEP=value3
`;
const updates = {
KEEP_ME: 'updated1',
ALSO_KEEP: 'updated3'
};
const result = editInString(original, updates);
// KEEP_ME=updated1
// ALSO_KEEP=updated3Handling Invalid Lines
The library gracefully handles lines without equals signs:
import { editInString } from '@hiscojs/dotenv-updater';
const original = `
VALID_KEY=value
INVALID_LINE_NO_EQUALS
ANOTHER_VALID=123
`;
const updates = {
VALID_KEY: 'newvalue',
INVALID_LINE_NO_EQUALS: 'fixed',
ANOTHER_VALID: '456'
};
const result = editInString(original, updates);
// VALID_KEY=newvalue
// INVALID_LINE_NO_EQUALS=fixed
// ANOTHER_VALID=456Working with File System
import fs from 'fs';
import { parse, editInString } from '@hiscojs/dotenv-updater';
// Read .env file
const envPath = '.env';
const content = fs.readFileSync(envPath, 'utf-8');
// Parse to get current values
const currentEnv = parse(content);
console.log('Current PORT:', currentEnv.PORT);
// Update with new values
const updates = {
...currentEnv,
PORT: '8080',
NEW_FEATURE_FLAG: 'true'
};
const updatedContent = editInString(content, updates);
// Write back to file
fs.writeFileSync(envPath, updatedContent, 'utf-8');Merging Environment Variables
import { parse, editInString } from '@hiscojs/dotenv-updater';
const defaultEnv = `
PORT=3000
HOST=localhost
`;
const productionOverrides = {
PORT: '80',
HOST: '0.0.0.0',
SSL_ENABLED: 'true'
};
// Merge defaults with overrides
const defaultParsed = parse(defaultEnv);
const merged = {
...defaultParsed,
...productionOverrides
};
const result = editInString(defaultEnv, merged);
// PORT=80
// HOST=0.0.0.0
// SSL_ENABLED=trueEdge Cases
Empty Values
const content = `KEY1=
KEY2=value2`;
const parsed = parse(content);
// { KEY1: undefined, KEY2: 'value2' }Multiline Values
const content = `MULTILINE=\`line1
line2
line3\``;
const parsed = parse(content);
// { MULTILINE: 'line1\nline2\nline3' }Keys with Dots and Hyphens
const content = `
my.dotted.key=value1
my-hyphenated-key=value2
`;
const parsed = parse(content);
// {
// 'my.dotted.key': 'value1',
// 'my-hyphenated-key': 'value2'
// }Special Characters in Values
const content = `
URL=https://example.com?foo=bar&baz=qux
[email protected]
PATH=/usr/local/bin:/usr/bin
`;
const parsed = parse(content);
// All special characters are preservedComparison with Other Libraries
vs. dotenv
- dotenv: Loads .env files into
process.env, read-only - @hiscojs/dotenv-updater: Parse AND update .env files, preserves formatting
vs. dotenv-expand
- dotenv-expand: Expands variables in .env files
- @hiscojs/dotenv-updater: Updates .env file content, removes unused keys
vs. Manual string manipulation
- Manual: Error-prone, doesn't preserve formatting
- @hiscojs/dotenv-updater: Robust parsing, formatting preservation, comment handling
Best Practices
1. Always Read Before Update
// ✅ Good - Preserves existing structure
const content = fs.readFileSync('.env', 'utf-8');
const updated = editInString(content, newVars);
fs.writeFileSync('.env', updated);
// ❌ Avoid - Loses all formatting
const updated = editInString('', newVars);
fs.writeFileSync('.env', updated);2. Keep Comments in Original File
// ✅ Good - Comments provide context
const original = `
# Production database
DB_HOST=prod-db.example.com
`;
// Comments are preserved when updating3. Use Consistent Quoting
// ✅ Good - Let the library handle quoting
const updates = {
SIMPLE: 'value',
COMPLEX: 'value with spaces'
};
// ❌ Avoid - Manual quoting
const updates = {
SIMPLE: '"value"', // Will be double-quoted
};4. Validate Values Before Update
// ✅ Good - Validate first
const updates = {
PORT: isValidPort(port) ? port : '3000',
HOST: isValidHost(host) ? host : 'localhost'
};
const result = editInString(content, updates);TypeScript Support
Full TypeScript support with type definitions included:
import { parse, editInString } from '@hiscojs/dotenv-updater';
const content: string = fs.readFileSync('.env', 'utf-8');
const parsed: Record<string, string | undefined> = parse(content);
const updates: Record<string, string | undefined> = {
PORT: '8080',
HOST: 'localhost'
};
const result: string = editInString(content, updates);License
MIT
Repository
https://github.com/hisco/dotenv-updater
Contributing
Issues and pull requests welcome!
