npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

strict-env-validator

v1.1.0

Published

Strict environment variable validation with CLI, type safety, auto-sync, and Vite support.

Readme

strict-env

Strict environment variable validation with CLI, type safety, and auto-sync.

npm version License: MIT

✨ Features

  • Type-safe environment variable validation
  • Zero-config setup (just call defineEnv())
  • 🛠 CLI supportcheck, generate, sync commands
  • 📄 Auto-generate .env.example from 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); // boolean

3. 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 value

num(config?)

Create a number validator. Automatically converts string to number.

num()                    // required number
num({ optional: true })  // optional number
num({ default: 3000 })   // default value

bool(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);    // number

viteStr(config?)

Vite string validator for client-side variables.

viteStr()                           // required string
viteStr({ optional: true })        // optional string
viteStr({ default: "localhost" })  // default value

viteNum(config?)

Vite number validator. Converts string to number at build-time.

viteNum()                    // required number
viteNum({ optional: true })  // optional number
viteNum({ default: 5173 })   // default value

viteBool(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 check

Output:

Environment Check Report

✅ All required variables are valid

Or 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 generate

Creates:

# 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 sync

Output:

✅ 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 missing

Invalid 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 template

3. 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.*.local

Commit:

env.schema.json  # commit this

5. 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.

💬 Support