Environment Variables
ScriptIt provides comprehensive environment variable management, allowing you to configure scripts for different environments, manage secrets securely, and access environment data within your scripts.
Overview
Environment variables in ScriptIt can be set through:
- Interactive prompts -
--env-prompts
flag or scriptvariables
export - Command-line flags -
--env VAR=value
- Configuration files -
scriptit.config.js
defaultParams .env
files - Loaded automatically- System environment variables -
export VAR=value
Environment Variable Priority
Variables are applied in the following order (highest to lowest priority):
- Interactive prompts - Variables collected via
--env-prompts
or scriptvariables
export - Command-line flags -
--env VAR=value
- Configuration file -
defaultParams
property in config .env
files - Loaded from project root and other configured files- System environment variables -
export VAR=value
Note: Variables that are already set (from any source) will not be prompted for interactively, ensuring no accidental overwrites.
Using .env Files
Basic .env File
Create a .env
file in your project root:
# .env
NODE_ENV=development
DEBUG=true
API_KEY=your-api-key-here
DATABASE_URL=postgresql://localhost:5432/mydb
PORT=3000
# Comments are supported
# Use quotes for values with spaces
APP_NAME="My ScriptIt App"
DESCRIPTION="A powerful script runner"
# Multi-line values (use quotes)
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7...
-----END PRIVATE KEY-----"
Environment-Specific .env Files
Create different .env
files for different environments:
project/
├── .env # Default/development
├── .env.local # Local overrides (gitignored)
├── .env.development # Development environment
├── .env.staging # Staging environment
├── .env.production # Production environment
└── .env.test # Test environment
.env.development
NODE_ENV=development
DEBUG=true
API_URL=http://localhost:3000
DATABASE_URL=postgresql://localhost:5432/myapp_dev
LOG_LEVEL=debug
.env.production
NODE_ENV=production
DEBUG=false
API_URL=https://api.myapp.com
DATABASE_URL=postgresql://prod-server:5432/myapp_prod
LOG_LEVEL=warn
Loading Environment-Specific Files
# Load development environment
NODE_ENV=development scriptit exec script.js
# Load production environment
NODE_ENV=production scriptit exec script.js
# Load staging environment
NODE_ENV=staging scriptit exec script.js
Accessing Environment Variables
In Scripts
Access environment variables through the context.env
object:
// script.js
export async function execute(context) {
const console = context.console || global.console;
// Access environment variables
const nodeEnv = context.env.NODE_ENV;
const apiKey = context.env.API_KEY;
const dbUrl = context.env.DATABASE_URL;
console.log('Environment:', nodeEnv);
console.log('API Key:', apiKey ? '***' : 'Not set');
console.log('Database URL:', dbUrl ? '***' : 'Not set');
// Validate required variables
if (!apiKey) {
throw new Error('API_KEY environment variable is required');
}
return { environment: nodeEnv, hasApiKey: !!apiKey };
}
Environment Validation
// validate-env.js
export const description = "Validate required environment variables";
const REQUIRED_VARS = [
'NODE_ENV',
'API_KEY',
'DATABASE_URL'
];
const OPTIONAL_VARS = [
'DEBUG',
'PORT',
'LOG_LEVEL'
];
export async function execute(context) {
const console = context.console || global.console;
console.info('🔍 Validating environment variables...');
const missing = [];
const present = [];
// Check required variables
for (const varName of REQUIRED_VARS) {
if (context.env[varName]) {
present.push(varName);
console.log(`✅ ${varName}: Set`);
} else {
missing.push(varName);
console.error(`❌ ${varName}: Missing`);
}
}
// Check optional variables
for (const varName of OPTIONAL_VARS) {
if (context.env[varName]) {
console.log(`✅ ${varName}: ${context.env[varName]}`);
} else {
console.warn(`⚠️ ${varName}: Not set (optional)`);
}
}
if (missing.length > 0) {
console.error(`❌ Missing required variables: ${missing.join(', ')}`);
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
console.info('✅ All required environment variables are set');
return { required: present, missing, environment: context.env.NODE_ENV };
}
Command-Line Environment Variables
Setting Variables
# Single variable
scriptit exec --env NODE_ENV=production script.js
# Multiple variables
scriptit exec --env NODE_ENV=production --env DEBUG=false --env PORT=8080 script.js
# With spaces (use quotes)
scriptit exec --env APP_NAME="My App" --env DESCRIPTION="A great app" script.js
Interactive Environment Prompts
ScriptIt supports interactive collection of environment variables, providing a secure way to input sensitive data without exposing it in command history or scripts.
Using --env-prompts Flag
# Prompt for specific variables before execution
scriptit exec --env-prompts API_KEY,SECRET_TOKEN script.js
# Space-separated format also works
scriptit exec --env-prompts API_KEY SECRET_TOKEN script.js
# Mix static and prompted variables
scriptit exec --env NODE_ENV=production --env-prompts API_KEY,DATABASE_PASSWORD script.js
# Works with TUI as well
scriptit run --env-prompts DATABASE_URL,API_KEY
Declarative Variable Definition in Scripts
Scripts can declare their required environment variables using the variables
export:
// deployment-script.js
export const description = "Deploy application with secure prompts";
// Full definition with custom prompts and types
export const variables = [
{ name: 'API_KEY', message: 'Enter your API key:', type: 'password' },
{ name: 'DEPLOY_ENV', message: 'Target environment (prod/staging):', type: 'input' },
'CONFIRM_DEPLOY' // Shorthand - generates default prompt
];
export async function execute(context) {
const console = context.console || global.console;
// Variables are automatically prompted and available in context.env
console.log(`Deploying to: ${context.env.DEPLOY_ENV}`);
console.log(`API Key: ${context.env.API_KEY ? '***hidden***' : 'Not set'}`);
if (context.env.CONFIRM_DEPLOY?.toLowerCase() !== 'yes') {
console.warn('Deployment cancelled by user');
return { cancelled: true };
}
// Proceed with deployment...
return { success: true };
}
Variable Types
input
(default): Regular text input, content visible as typedpassword
: Hidden input with masked characters (*
)
Smart Variable Detection
ScriptIt automatically detects which variables need to be collected:
- Skip existing - Variables already set in environment are not prompted
- Combine sources - CLI
--env-prompts
+ scriptvariables
export - Precedence handling - CLI prompts take precedence over script declarations
- Security first - Prompted values are never logged or displayed
Combining with Other Options
# With runtime selection
scriptit --runtime=bun exec --env NODE_ENV=production script.js
# With config file
scriptit exec --config prod.config.js --env API_KEY=secret script.js
# With working directory
scriptit --pwd /app exec --env NODE_ENV=production deploy.js
Configuration File Environment Variables
Basic Configuration
// scriptit.config.js
export default {
env: {
NODE_ENV: 'development',
DEBUG: 'true',
API_URL: 'http://localhost:3000',
LOG_LEVEL: 'debug'
}
}
Dynamic Configuration
// scriptit.config.js
export default {
env: {
NODE_ENV: process.env.NODE_ENV || 'development',
DEBUG: process.env.DEBUG || 'false',
API_URL: process.env.API_URL || 'http://localhost:3000',
// Computed values
IS_PRODUCTION: process.env.NODE_ENV === 'production',
IS_DEVELOPMENT: process.env.NODE_ENV === 'development',
// Default values with fallbacks
PORT: process.env.PORT || '3000',
HOST: process.env.HOST || 'localhost'
}
}
Environment-Specific Configuration
// scriptit.config.js
const environments = {
development: {
env: {
NODE_ENV: 'development',
DEBUG: 'true',
API_URL: 'http://localhost:3000',
LOG_LEVEL: 'debug'
}
},
staging: {
env: {
NODE_ENV: 'staging',
DEBUG: 'false',
API_URL: 'https://staging-api.myapp.com',
LOG_LEVEL: 'info'
}
},
production: {
env: {
NODE_ENV: 'production',
DEBUG: 'false',
API_URL: 'https://api.myapp.com',
LOG_LEVEL: 'warn'
}
}
};
const currentEnv = process.env.NODE_ENV || 'development';
export default environments[currentEnv];
ScriptIt-Specific Environment Variables
Built-in Variables
Variable | Description | Example |
---|---|---|
SCRIPTIT_RUNTIME | Default runtime to use | bun , deno , node |
SCRIPTIT_DEBUG | Enable debug mode | true , false |
SCRIPTIT_CONFIG | Path to config file | ./custom.config.js |
SCRIPTIT_SCRIPTS_DIR | Scripts directory | ./src/scripts |
SCRIPTIT_TMP_DIR | Temporary directory | ./temp |
Usage Examples
# Set default runtime
export SCRIPTIT_RUNTIME=bun
scriptit exec script.js
# Enable debug mode
export SCRIPTIT_DEBUG=true
scriptit run
# Custom config file
export SCRIPTIT_CONFIG=./prod.config.js
scriptit exec deploy.js
# Custom directories
export SCRIPTIT_SCRIPTS_DIR=./src/scripts
export SCRIPTIT_TMP_DIR=./temp
scriptit run
Environment Variable Patterns
1. Configuration Pattern
// config-script.js
export const description = "Configuration management script";
export async function execute(context) {
const console = context.console || global.console;
const config = {
environment: context.env.NODE_ENV || 'development',
debug: context.env.DEBUG === 'true',
api: {
url: context.env.API_URL || 'http://localhost:3000',
key: context.env.API_KEY,
timeout: parseInt(context.env.API_TIMEOUT || '5000')
},
database: {
url: context.env.DATABASE_URL,
pool: {
min: parseInt(context.env.DB_POOL_MIN || '2'),
max: parseInt(context.env.DB_POOL_MAX || '10')
}
}
};
console.info('📋 Configuration loaded:');
console.log('Environment:', config.environment);
console.log('Debug mode:', config.debug);
console.log('API URL:', config.api.url);
console.log('API Key:', config.api.key ? '***' : 'Not set');
return config;
}
2. Feature Flags Pattern
// feature-flags.js
export const description = "Feature flags management";
export async function execute(context) {
const console = context.console || global.console;
const features = {
newUI: context.env.FEATURE_NEW_UI === 'true',
betaFeatures: context.env.FEATURE_BETA === 'true',
analytics: context.env.FEATURE_ANALYTICS !== 'false', // Default true
debugging: context.env.FEATURE_DEBUG === 'true'
};
console.info('🚩 Feature flags:');
Object.entries(features).forEach(([name, enabled]) => {
const status = enabled ? '✅ Enabled' : '❌ Disabled';
console.log(`${name}: ${status}`);
});
return features;
}
3. Secrets Management Pattern
// secrets.js
export const description = "Secure secrets management";
export async function execute(context) {
const console = context.console || global.console;
const secrets = {
apiKey: context.env.API_KEY,
dbPassword: context.env.DB_PASSWORD,
jwtSecret: context.env.JWT_SECRET,
encryptionKey: context.env.ENCRYPTION_KEY
};
// Validate all secrets are present
const missingSecrets = Object.entries(secrets)
.filter(([name, value]) => !value)
.map(([name]) => name);
if (missingSecrets.length > 0) {
console.error('❌ Missing secrets:', missingSecrets.join(', '));
throw new Error(`Missing required secrets: ${missingSecrets.join(', ')}`);
}
console.info('🔐 All secrets loaded successfully');
// Return without exposing actual values
return {
secretsLoaded: Object.keys(secrets),
allPresent: missingSecrets.length === 0
};
}
Environment Variable Security
Best Practices
- Never commit secrets to version control:
# .gitignore
.env.local
.env.*.local
.env.production
*.key
*.pem
- Use different files for different environments:
// ✅ Good - environment-specific files
.env.development # Development secrets
.env.staging # Staging secrets
.env.production # Production secrets (never committed)
// ❌ Bad - single file with all secrets
.env # Contains production secrets
- Validate required variables:
// ✅ Good - validate at startup
export async function execute(context) {
const required = ['API_KEY', 'DATABASE_URL', 'JWT_SECRET'];
const missing = required.filter(name => !context.env[name]);
if (missing.length > 0) {
throw new Error(`Missing: ${missing.join(', ')}`);
}
}
// ❌ Bad - fail silently
export async function execute(context) {
const apiKey = context.env.API_KEY || 'default-key';
}
Secret Rotation
// secret-rotation.js
export const description = "Check for secret rotation needs";
export async function execute(context) {
const console = context.console || global.console;
const secrets = [
{ name: 'API_KEY', lastRotated: context.env.API_KEY_ROTATED },
{ name: 'JWT_SECRET', lastRotated: context.env.JWT_SECRET_ROTATED },
{ name: 'DB_PASSWORD', lastRotated: context.env.DB_PASSWORD_ROTATED }
];
const now = new Date();
const rotationThreshold = 90 * 24 * 60 * 60 * 1000; // 90 days
secrets.forEach(secret => {
if (!secret.lastRotated) {
console.warn(`⚠️ ${secret.name}: No rotation date set`);
return;
}
const lastRotated = new Date(secret.lastRotated);
const daysSince = Math.floor((now - lastRotated) / (24 * 60 * 60 * 1000));
if (daysSince > 90) {
console.error(`❌ ${secret.name}: Needs rotation (${daysSince} days old)`);
} else {
console.log(`✅ ${secret.name}: OK (${daysSince} days old)`);
}
});
return { secrets, checkDate: now.toISOString() };
}
Environment Variable Templates
Development Template
# .env.development
NODE_ENV=development
DEBUG=true
# API Configuration
API_URL=http://localhost:3000
API_KEY=dev-api-key-123
API_TIMEOUT=10000
# Database Configuration
DATABASE_URL=postgresql://localhost:5432/myapp_dev
DB_POOL_MIN=2
DB_POOL_MAX=10
# Feature Flags
FEATURE_NEW_UI=true
FEATURE_BETA=true
FEATURE_ANALYTICS=false
FEATURE_DEBUG=true
# Logging
LOG_LEVEL=debug
LOG_FORMAT=pretty
# Development Tools
HOT_RELOAD=true
SOURCE_MAPS=true
Production Template
# .env.production (DO NOT COMMIT)
NODE_ENV=production
DEBUG=false
# API Configuration
API_URL=https://api.myapp.com
API_KEY=prod-api-key-secure
API_TIMEOUT=5000
# Database Configuration
DATABASE_URL=postgresql://prod-server:5432/myapp_prod
DB_POOL_MIN=5
DB_POOL_MAX=50
# Feature Flags
FEATURE_NEW_UI=true
FEATURE_BETA=false
FEATURE_ANALYTICS=true
FEATURE_DEBUG=false
# Logging
LOG_LEVEL=warn
LOG_FORMAT=json
# Security
JWT_SECRET=super-secure-jwt-secret
ENCRYPTION_KEY=32-char-encryption-key-here
Troubleshooting
Common Issues
Variable not found:
❌ ScriptIt Error: Required environment variable API_KEY not found
💡 Set the variable: export API_KEY=your-key
💡 Or add to .env file: API_KEY=your-key
Invalid .env file:
❌ ScriptIt Error: Invalid .env file syntax at line 5
💡 Check for missing quotes or invalid characters
Variable override conflicts:
⚠️ Warning: API_KEY overridden by command line
💡 Command-line --env flags take precedence over .env files
Debug Environment Variables
Use debug mode to see environment variable loading:
scriptit --debug exec script.js
Output includes:
- Loaded .env files
- Environment variable sources
- Final merged environment
- Variable precedence information
Environment Variable Inspection
// inspect-env.js
export const description = "Inspect environment variables";
export async function execute(context) {
const console = context.console || global.console;
console.info('🔍 Environment Variables:');
// Group by prefix
const groups = {};
Object.keys(context.env).forEach(key => {
const prefix = key.split('_')[0];
if (!groups[prefix]) groups[prefix] = [];
groups[prefix].push(key);
});
// Display grouped variables
Object.entries(groups).forEach(([prefix, keys]) => {
console.log(`\n📁 ${prefix}:`);
keys.forEach(key => {
const value = context.env[key];
const displayValue = key.toLowerCase().includes('secret') ||
key.toLowerCase().includes('key') ||
key.toLowerCase().includes('password')
? '***' : value;
console.log(` ${key}: ${displayValue}`);
});
});
return { totalVariables: Object.keys(context.env).length, groups };
}
Related Documentation
- CLI Commands - Command-line environment options
- Configuration - Configuration file environment settings
- Runtime Selection - Runtime-specific environment variables
- Examples - Environment variable examples