dotenv-gad is an environment variable validation tool that brings type safety and schema validation to your Node.js and JavaScript applications. It extends dotenv with features like:
- Type-safe environment variables
- Schema validation
- Schema composition
- Automatic documentation generation
- TypeScript support
- CLI tooling
- Secret management
npm install dotenv-gad
# or
yarn add dotenv-gad
# or
pnpm add dotenv-gad- Create a schema file (
env.schema.ts):
import { defineSchema } from "dotenv-gad";
export default defineSchema({
PORT: {
type: "number",
default: 3000,
docs: "Port to run the server on",
},
DATABASE_URL: {
type: "string",
required: true,
sensitive: true,
},
});- Validate your environment:
import { loadEnv } from "dotenv-gad";
import schema from "./env.schema";
const env = loadEnv(schema);
console.log(`Server running on port ${env.PORT}`);Documentation
Full documentation is available via GitHub Pages (published from docs/).
To preview locally:
npm ci
npm run docs:serveDocs preview on PRs
When you open or update a pull request that changes docs, an automated preview will be published to GitHub Pages under previews/pr-<number>/ and a comment with the preview link will be posted on the PR. This makes it easy to review documentation changes without merging.
| Command | Description |
|---|---|
check |
Validate .env against schema |
sync |
Generate/update .env.example |
types |
Generate env.d.ts TypeScript types |
init |
Create starter schema |
fix |
Fixes environment issues |
docs |
Generates .env documentation |
npx dotenv-gad check
npx dotenv-gad types- Type checking (string, number, boolean, array, object)
- Required/optional fields
- Default values
- Custom validation functions
- Environment-specific rules
{
API_URL: { type: 'url' },
EMAIL: { type: 'email' },
CONFIG: { type: 'json' },
TAGS: {
type: 'array',
items: { type: 'string' }
}
}- Color-coded output
- Interactive fixes
- Strict mode
- Custom schema paths
- CI/CD friendly
{
API_KEY: {
type: 'string',
sensitive: true, // Excluded from .env.example
validate: (val) => val.startsWith('sk_')
}
}import express from "express";
import { loadEnv } from "dotenv-gad";
import schema from "./env.schema";
const env = loadEnv(schema);
const app = express();
app.listen(env.PORT, () => {
console.log(`Server running on port ${env.PORT}`);
});Create next.config.js:
const { loadEnv } = require("dotenv-gad");
const schema = require("./env.schema");
const env = loadEnv(schema);
module.exports = {
env: {
API_URL: env.API_URL,
},
};Example error output:
Environment validation failed:
- DATABASE_URL: Missing required environment variable
- PORT: Must be a number (received: "abc")
- API_KEY: Must start with 'sk_' (received: "invalid")
By default values in the report are redacted (sensitive values are always masked). You can opt-in to include raw values in error reports when instantiating the validator (useful for local debugging) by using the includeRaw option. If you also want to reveal values marked as sensitive: true set includeSensitive to true (use with caution).
// include raw values in errors (non-sensitive values only)
import { loadEnv } from "dotenv-gad";
const env = loadEnv(schema, { includeRaw: true });
// or with finer control
import { EnvValidator } from "dotenv-gad";
const validator = new EnvValidator(schema, { includeRaw: true, includeSensitive: true });
try {
validator.validate(process.env);
} catch (err) {
console.error(String(err));
}{
DEBUG: {
type: 'boolean',
env: {
development: { default: true },
production: { default: false }
}
}
}{
PASSWORD: {
type: 'string',
validate: (val) => val.length >= 8,
error: 'Password must be at least 8 characters'
}
}{
FEATURES: {
type: 'array',
transform: (val) => val.split(',')
}
}You can group related environment variables into a single object using object with properties and an optional envPrefix (defaults to KEY_):
const schema = defineSchema({
DATABASE: {
type: 'object',
envPrefix: 'DATABASE_', // optional; defaults to 'DATABASE_'
properties: {
DB_NAME: { type: 'string', required: true },
PORT: { type: 'port', default: 5432 },
PWD: { type: 'string', sensitive: true }
}
}
});Given the following environment:
DATABASE_DB_NAME=mydb
DATABASE_PORT=5432
DATABASE_PWD=supersecret
loadEnv(schema) will return:
{ DATABASE: { DB_NAME: 'mydb', PORT: 5432, PWD: 'supersecret' } }Notes and behavior:
- The default
envPrefixis${KEY}_(forDATABASEit'sDATABASE_) if you don't specifyenvPrefix. - Prefixed variables take precedence over a JSON top-level env var (e.g.,
DATABASE= '{...}'). If both are present, prefixed variables win and a warning is printed. - In strict mode (
{ strict: true }), unexpected subkeys inside a group (e.g.,DATABASE_EXTRA) will cause validation to fail. sensitiveandincludeRawbehavior still applies for grouped properties: sensitive properties are still masked in errors unlessincludeSensitiveis explicitly set.
The CLI sync command will now generate grouped entries in .env.example for object properties so it's easier to scaffold grouped configuration.
MIT © [Kasim Lyee]
Contributions are welcome!!