Type-Safe by Design
Full TypeScript support with compile-time validation of environment configurations and variable usage.
Zero Dependencies
Lightweight and secure with no external runtime dependencies.
Flexible Resolution
Support for multiple resolution strategies including environment variables, secrets, and custom methods.
Environment Registry
Centralized management of multiple environments (local, staging, production) with distinct configurations.
Async Support
Handle both synchronous and asynchronous variable resolution, perfect for external secrets managers.
Secure by Default
Built-in protection against accidental logging of sensitive values through redacted data patterns.
See it in Action
import { createEnvironmentRegistry, defineType } from 'envoyage'
// Define environments with type-safe configurations
const envReg = createEnvironmentRegistry()
.addEnv("local", defineType<{ env: Record<string, string> }>(), (env) => env
.addResolution("from-env", defineType<undefined>(), (data) =>
data.envData.env[data.variableName]))
.addEnv("prod", defineType<{ secrets: Record<string, string> }>(), (env) => env
.addResolution("from-secrets", defineType<undefined>(), (data) =>
data.envData.secrets[data.variableName]))
// Define variables with environment-specific resolution
const varReg = envReg.createVariableRegistry()
.addVar("DATABASE_URL", (v) => v
.for("local", "from-env")
.for("prod", "from-secrets"))
// Create a resolver and use variables
const resolver = varReg.createResolver("local", {
env: process.env
})
const dbUrl = resolver.get("DATABASE_URL")