This guide will help you get up and running with Load Env quickly.
Basic Setup
Create .env file
Create a .env file in your project root: PORT = 3000
DATABASE_URL = postgresql://localhost:5432/mydb
DEBUG = true
API_KEY = your-secret-key
Load environment variables
Import and call loadEnv() at the start of your application: import { loadEnv } from "@natoboram/load_env"
// Load .env files based on NODE_ENV
await loadEnv ()
Access variables with type safety
Use type-safe functions to access your environment variables: import { envInt , envString , envBool } from "@natoboram/load_env"
export const PORT = envInt ( "PORT" , 3000 )
export const DATABASE_URL = envString ( "DATABASE_URL" )
export const DEBUG = envBool ( "DEBUG" , false )
export const API_KEY = envString ( "API_KEY" )
Complete Example
Here’s a complete example showing all the type-safe functions:
import {
loadEnv ,
envBool ,
envString ,
envInt ,
envFloat ,
envDate ,
envUrl ,
envUuid ,
envEnum ,
envStrings ,
} from "@natoboram/load_env"
import type { UUID } from "node:crypto"
// Load environment variables first
await loadEnv ()
// Required variables (will throw if missing)
export const PORT = envInt ( "PORT" , 3000 )
export const DATABASE_URL = envUrl ( "DATABASE_URL" )
export const API_KEY = envString ( "API_KEY" )
// Boolean variables
export const DEBUG = envBool ( "DEBUG" , false )
export const ENABLE_LOGGING = envBool ( "ENABLE_LOGGING" , true )
// Numeric variables
export const MAX_CONNECTIONS = envInt ( "MAX_CONNECTIONS" , 100 )
export const TIMEOUT_SECONDS = envFloat ( "TIMEOUT_SECONDS" , 30.5 )
// Date variables
export const START_DATE = envDate ( "START_DATE" , new Date ())
// UUID variables
export const SERVICE_ID = envUuid ( "SERVICE_ID" )
// Enum variables (constrained to specific values)
export const NODE_ENV = envEnum (
"NODE_ENV" ,
[ "development" , "production" , "test" ] as const ,
"development"
)
// Array of strings (comma-separated)
export const ALLOWED_ORIGINS = envStrings (
"ALLOWED_ORIGINS" ,
[ "http://localhost:3000" ]
)
Optional Variables
Use the maybe* variants for optional environment variables:
import {
maybeEnvString ,
maybeEnvInt ,
maybeEnvBool ,
maybeEnvUrl ,
} from "@natoboram/load_env"
// These return undefined if not set
export const OPTIONAL_API_KEY = maybeEnvString ( "OPTIONAL_API_KEY" )
export const OPTIONAL_PORT = maybeEnvInt ( "OPTIONAL_PORT" )
export const OPTIONAL_DEBUG = maybeEnvBool ( "OPTIONAL_DEBUG" )
export const OPTIONAL_URL = maybeEnvUrl ( "OPTIONAL_URL" )
// Use with defaults
const port = OPTIONAL_PORT ?? 3000
const debug = OPTIONAL_DEBUG ?? false
Environment-Specific Files
Load Env automatically loads the correct .env files based on NODE_ENV:
.env
.env.development
.env.production
.env.local
# Loaded in all environments
APP_NAME = MyApp
DEFAULT_LOCALE = en
Add .env*.local files to your .gitignore to keep local overrides out of version control
Custom .env Path
By default, Load Env looks for .env files in the current directory. You can specify a custom path:
import { loadEnv } from "@natoboram/load_env"
await loadEnv ({ path: "./config" })
Type Definitions
Here are the type signatures for the main functions:
// Required variables with optional fallback
function envString ( key : string , fallback ?: string ) : string
function envInt ( key : string , fallback ?: number ) : number
function envFloat ( key : string , fallback ?: number ) : number
function envBool ( key : string , fallback ?: boolean ) : boolean
function envDate ( key : string , fallback ?: Date ) : Date
function envUrl ( key : string , fallback ?: URL ) : URL
function envUuid ( key : string , fallback ?: UUID ) : UUID
function envEnum < T extends string []>(
key : string ,
values : T ,
fallback ?: T [ number ]
) : T [ number ]
function envStrings ( key : string , fallback ?: string []) : string []
// Optional variables (return undefined if not set)
function maybeEnvString ( key : string ) : string | undefined
function maybeEnvInt ( key : string ) : number | undefined
function maybeEnvFloat ( key : string ) : number | undefined
function maybeEnvBool ( key : string ) : boolean | undefined
function maybeEnvDate ( key : string ) : Date | undefined
function maybeEnvUrl ( key : string ) : URL | undefined
function maybeEnvUuid ( key : string ) : UUID | undefined
function maybeEnvEnum < T extends string []>(
key : string ,
values : T
) : T [ number ] | undefined
function maybeEnvStrings ( key : string ) : string [] | undefined
Working with Secrets
Load Env supports loading secrets from the filesystem, which is useful for Docker Compose secrets:
import { secretString , secretInt , maybeSecretString } from "@natoboram/load_env"
// Load secrets from filesystem
// The env var should contain the path to the secret file
export const DB_PASSWORD = await secretString ( "DB_PASSWORD" )
export const API_TOKEN = await secretString ( "API_TOKEN" )
// Optional secrets
export const OPTIONAL_SECRET = await maybeSecretString ( "OPTIONAL_SECRET" )
// With fallback
export const SECRET_KEY = await secretString ( "SECRET_KEY" , "default-key" )
Secret functions are async and must be awaited. The environment variable should contain the path to a file containing the secret value.
Docker Compose Example
services :
app :
image : myapp
environment :
- DB_PASSWORD=/run/secrets/db_password
secrets :
- db_password
secrets :
db_password :
file : ./secrets/db_password.txt
Learn more:
Error Handling
Load Env throws descriptive errors when variables are missing or invalid:
import { envInt , envUrl } from "@natoboram/load_env"
try {
const port = envInt ( "PORT" ) // Throws if PORT is not set
const url = envUrl ( "API_URL" ) // Throws if API_URL is not a valid URL
} catch ( error ) {
console . error ( "Configuration error:" , error . message )
process . exit ( 1 )
}
Required functions (without the maybe prefix) will throw an error if the environment variable is not set or cannot be parsed correctly.
Next Steps
API Reference Explore all available functions and their usage
Guides Learn about loading .env files and advanced usage