strict-env-validator
v1.1.0
Published
Strict environment variable validation with CLI, type safety, auto-sync, and Vite support.
Maintainers
Readme
strict-env
Strict environment variable validation with CLI, type safety, and auto-sync.
✨ Features
- ✅ Type-safe environment variable validation
- ⚡ Zero-config setup (just call
defineEnv()) - 🛠 CLI support —
check,generate,synccommands - 📄 Auto-generate
.env.examplefrom your schema - 🚨 Clear, developer-friendly errors with hints
- 🎯 Fully typed with TypeScript support
- 🔧 Support for string, number, boolean types
- 💾 Default values for optional variables
📦 Installation
npm install strict-env
# or
yarn add strict-env
# or
pnpm add strict-env🚀 Quick Start
1. Define your environment schema
Create env.schema.json in your project root:
{
"DATABASE_URL": {
"type": "string",
"optional": false
},
"PORT": {
"type": "number",
"optional": false,
"default": 3000
},
"DEBUG": {
"type": "boolean",
"optional": true
}
}2. Use in your code
import { defineEnv, str, num, bool } from "strict-env";
export const env = defineEnv({
DATABASE_URL: str(),
PORT: num({ default: 3000 }),
DEBUG: bool({ optional: true }),
});
// Use safely
console.log(env.DATABASE_URL); // string
console.log(env.PORT); // number
console.log(env.DEBUG); // boolean3. Create .env file
DATABASE_URL=postgresql://localhost/mydb
PORT=5000
DEBUG=true📖 API Reference
defineEnv(schema)
Validates environment variables against your schema. Returns a typed object.
import { defineEnv, str, num, bool } from "strict-env";
const env = defineEnv({
DATABASE_URL: str(),
PORT: num(),
DEBUG: bool({ optional: true }),
});Throws: Exits process if validation fails.
str(config?)
Create a string validator.
str() // required string
str({ optional: true }) // optional string
str({ default: "localhost" }) // default valuenum(config?)
Create a number validator. Automatically converts string to number.
num() // required number
num({ optional: true }) // optional number
num({ default: 3000 }) // default valuebool(config?)
Create a boolean validator. Accepts "true", "1", "yes" as true.
bool() // required boolean
bool({ optional: true }) // optional boolean
bool({ default: false }) // default value🌐 Vite Support (React, Vue, Svelte)
defineViteEnv(schema, importMetaEnv?)
Validates Vite environment variables at build-time. Variables must be prefixed with VITE_PUBLIC_* to be accessible in browser code.
import { defineViteEnv, viteStr, viteNum, viteBool } from "strict-env/vite";
const env = defineViteEnv({
VITE_PUBLIC_API_URL: viteStr(),
VITE_PUBLIC_PORT: viteNum({ default: 5173 }),
VITE_PUBLIC_DEBUG: viteBool({ optional: true }),
});
console.log(env.VITE_PUBLIC_API_URL); // string
console.log(env.VITE_PUBLIC_PORT); // numberviteStr(config?)
Vite string validator for client-side variables.
viteStr() // required string
viteStr({ optional: true }) // optional string
viteStr({ default: "localhost" }) // default valueviteNum(config?)
Vite number validator. Converts string to number at build-time.
viteNum() // required number
viteNum({ optional: true }) // optional number
viteNum({ default: 5173 }) // default valueviteBool(config?)
Vite boolean validator. Accepts "true", "1", "yes".
viteBool() // required boolean
viteBool({ optional: true }) // optional boolean
viteBool({ default: false }) // default value🛠 CLI Commands
Check environment
Validates all required variables without running your app:
npx strict-env checkOutput:
Environment Check Report
✅ All required variables are validOr with errors:
❌ Missing or invalid variables:
- DATABASE_URL (required)
- PORT (expected number, got "abc")Generate .env.example
Auto-generates .env.example from your schema:
npx strict-env generateCreates:
# Environment Variables
# Copy this file to .env and fill in the values
# DATABASE_URL - string
DATABASE_URL=
# PORT - number - default: 3000
PORT=
# DEBUG - boolean (optional)
DEBUG=Sync environment files
Creates .env and .env.example, keeping them in sync:
npx strict-env syncOutput:
✅ Synced .env.example
✅ Created .env🎯 Error Handling
Missing required variable
defineEnv({
DATABASE_URL: str(),
});
// If DATABASE_URL is not in .env:
// ❌ Environment Validation Failed:
// - DATABASE_URL: Required variable is missingInvalid type
defineEnv({
PORT: num(),
});
// If PORT=abc in .env:
// ❌ Environment Validation Failed:
// - PORT: Expected number, got "abc"💡 Best Practices
1. Create schema file
Always use env.schema.json for CLI commands:
{
"DATABASE_URL": { "type": "string" },
"PORT": { "type": "number", "default": 3000 },
"DEBUG": { "type": "boolean", "optional": true }
}2. Separate dev from production
Use different .env files:
.env # local development
.env.prod # production template3. Use in application entry point
Import early in your app:
// src/main.ts
import { env } from "./env";
console.log(`Server running on port ${env.PORT}`);4. Commit schema, ignore values
In .gitignore:
.env
.env.local
.env.*.localCommit:
env.schema.json # commit this5. Use CLI in CI/CD
Add to your pipeline:
# .github/workflows/test.yml
- run: npx strict-env check
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PORT: 3000📋 Examples
Next.js
// lib/env.ts
import { defineEnv, str, num, bool } from "strict-env";
export const env = defineEnv({
NEXT_PUBLIC_API_URL: str(),
DATABASE_URL: str(),
JWT_SECRET: str(),
DEBUG: bool({ optional: true }),
});Express
// src/env.ts
import { defineEnv, str, num } from "strict-env";
export const env = defineEnv({
PORT: num({ default: 3000 }),
DATABASE_URL: str(),
NODE_ENV: str(),
});NestJS
// src/common/env.ts
import { defineEnv, str, num } from "strict-env";
export const env = defineEnv({
PORT: num({ default: 3000 }),
DATABASE_URL: str(),
JWT_SECRET: str(),
});
// main.ts
import { env } from "./common/env";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(env.PORT);
}React + Vite
// src/env.ts
import { defineViteEnv, viteStr } from "strict-env/vite";
export const env = defineViteEnv({
VITE_PUBLIC_API_URL: viteStr(),
VITE_PUBLIC_APP_NAME: viteStr(),
});
// src/App.tsx
import { env } from "./env";
function App() {
return (
<div>
<h1>{env.VITE_PUBLIC_APP_NAME}</h1>
<p>API: {env.VITE_PUBLIC_API_URL}</p>
</div>
);
}Vue + Vite
// src/env.ts
import { defineViteEnv, viteStr, viteNum } from "strict-env/vite";
export const env = defineViteEnv({
VITE_PUBLIC_API_URL: viteStr(),
VITE_PUBLIC_PORT: viteNum({ default: 5173 }),
});
// src/App.vue
<template>
<div>
<h1>{{ appName }}</h1>
<p>API: {{ apiUrl }}</p>
</div>
</template>
<script setup lang="ts">
import { env } from "./env";
const appName = "My Vue App";
const apiUrl = env.VITE_PUBLIC_API_URL;
</script>🔄 Version History
v1.1.0 (Current)
- ✅ Core validation library (Node.js)
- ✅ NEW: Vite support for React, Vue, Svelte
- ✅ TypeScript support
- ✅ CLI tooling (check, generate, sync)
- ✅ Type validators (str, num, bool)
- ✅ Default values & optional variables
- ✅ Clear error messages
v1.0.0
- ✅ Core validation library
- ✅ TypeScript support
- ✅ CLI tooling (check, generate, sync)
- ✅ Type validators (str, num, bool)
- ✅ Default values & optional variables
- ✅ Clear error messages
📝 License
MIT © Your Name
🤝 Contributing
Contributions welcome! Feel free to submit issues and pull requests.
