
A modern approach to environment variables using JSON instead of .env files, with built-in validation via JSON schema.
.env to JSON formatcomposer require koriym/env-json
// Load and validate environment variables
$env = (new EnvJson())->load(__DIR__);
// Access variables as object properties
echo $env->DATABASE_URL;
// Or use traditional getenv()
echo getenv('DATABASE_URL');
Define your environment variables with types, descriptions, and constraints:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"DATABASE_URL", "API_KEY"
],
"properties": {
"DATABASE_URL": {
"description": "Connection string for the database",
"pattern": "^mysql://.*"
},
"API_KEY": {
"description": "Authentication key for external API",
"minLength": 32
},
"DEBUG_MODE": {
"description": "Enable debug output (true/false)",
"enum": ["true", "false"],
"default": "false"
},
"PORT": {
"description": "Server port number",
"pattern": "^[0-9]+$",
"default": "3000"
}
}
}
Your actual configuration values:
{
"$schema": "./env.schema.json",
"DATABASE_URL": "mysql://user:pass@localhost/mydb",
"API_KEY": "1234567890abcdef1234567890abcdef",
"DEBUG_MODE": "true",
"PORT": "8080"
}
Environment variables are always treated as strings. Using non-string types in your JSON schema will cause validation errors.
{
"DEBUG_MODE": {
"type": "boolean",
"default": false
},
"PORT": {
"type": "integer",
"default": 3000
},
"TIMEOUT": {
"type": "number",
"default": 30.5
}
}
Error message: The value will be a string (e.g., “3000”), but the schema expects an integer, causing validation to fail.
{
"DEBUG_MODE": {
"description": "Enable debug output (true/false)",
"enum": ["true", "false"],
"default": "false"
},
"PORT": {
"description": "Server port number",
"pattern": "^[0-9]+$",
"default": "3000"
},
"TIMEOUT": {
"description": "Timeout in seconds",
"pattern": "^[0-9]+(\\.[0-9]+)?$",
"default": "30.5"
}
}
Boolean values:
"FEATURE_ENABLED": {
"enum": ["true", "false"],
"default": "false"
}
Numeric values:
"TIMEOUT": {
"pattern": "^[0-9]+$",
"default": "30"
}
Enum values:
"LOG_LEVEL": {
"enum": ["debug", "info", "warning", "error"],
"default": "info"
}
env.schema.json with all required variables, patterns, and constraintsenv.dist.json with default/sample values that can be shared with the teamenv.json with your specific local values (add to .gitignore)env.json if presentenv.json is not found, it falls back to env.dist.jsonenv.dist.json during deployment (not needed in production)env.json (should be in .gitignore)Convert your existing .env files to JSON format:
bin/ini2json .env
This generates both env.schema.json and env.dist.json files.
The envjson command line tool helps you integrate with various environments:
# Load variables into current shell
source <(bin/envjson)
# Specify custom directory
source <(bin/envjson -d ./config)
# Output in PHP-FPM format: env[FOO] = "foo1"
bin/envjson -d ./config -o fpm > .env.fpm
# Output in INI format: FOO="foo1"
bin/envjson -d ./config -o ini > env.ini
# Output in shell format: export FOO="foo1"
bin/envjson -d ./config -o shell > env.sh
-d --dir=DIR Directory containing env files (default: current directory)
-f --file=FILE JSON file name to load (default: env.json)
-o --output=FMT Output format: shell, fpm, ini (default: shell)
-v --verbose Show detailed messages
-q --quiet Suppress all warning messages
-h --help Display help message