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

@withtahmid/safenv

v1.0.4

Published

gives types to env variables

Readme

🔧 Safenv

Type-safe environment variable configuration with intelligent validation and parsing

TypeScript License NPM Version

✨ Features

  • 🎯 Type-Safe: Full TypeScript support with automatic type inference
  • 💡 IntelliSense: Auto-completion and suggestions for your environment variables
  • Validation: Built-in validation for required and optional variables
  • 🔄 Type Parsing: Automatic parsing for strings, numbers, and booleans
  • 📝 Smart Logging: Comprehensive error and warning messages
  • 🛡️ Fail-Fast: Throws errors on validation failure to prevent runtime issues
  • 🎨 Clean API: Simple, intuitive configuration schema

📦 Installation

npm install @withtahmid/safenv
yarn add @withtahmid/safenv
pnpm add @withtahmid/safenv

🚀 Quick Start

import { configEnv, e } from "@withtahmid/safenv";

const env = configEnv(process.env, {
    PORT: e.number().default(3000),
    HOST: e.string(),
    DEBUG: e.boolean().default(false),
    API_KEY: e.string(),
    MAX_RETRIES: e.number().optional(),
});

// Use with full type safety and IntelliSense
console.log(env.PORT); // number
console.log(env.HOST); // string
console.log(env.DEBUG); // boolean
console.log(env.API_KEY); // string
console.log(env.MAX_RETRIES); // number | undefined

💡 IntelliSense Support

Get auto-completion for all your environment variables:

Environment Variable Suggestions

📊 Smart Error & Warning Messages

Clear feedback during application startup:

Error and Warning Messages

Example output:

[warn]   Env variable PORT is not set, using default value: 3000
[warn]   Env variable DEBUG is not set, using default value: false
[warn]   Optional env variable MAX_RETRIES is not set and has no default value
[error]  Missing required env variable: HOST
[error]  Missing required env variable: API_KEY
[info]   Environment variables loaded successfully

📖 Usage

Basic Configuration

import { configEnv, e } from "@withtahmid/safenv";

const env = configEnv(process.env, {
    DATABASE_URL: e.string(),
    PORT: e.number().default(8080),
    ENABLE_CACHE: e.boolean().default(true),
});

Supported Types

String (Required by default)

const env = configEnv(process.env, {
    API_URL: e.string(),
    API_KEY: e.string().default("default-key"),
    OPTIONAL_VAR: e.string().optional(),
});

Number (Required by default)

const env = configEnv(process.env, {
    PORT: e.number(),
    MAX_CONNECTIONS: e.number().default(100),
    TIMEOUT: e.number().optional(),
});

Boolean (Required by default)

Accepts: true, false, 1, 0

const env = configEnv(process.env, {
    DEBUG: e.boolean(),
    ENABLE_LOGGING: e.boolean().default(false),
    FEATURE_FLAG: e.boolean().optional(),
});

Modifiers

.optional()

Makes the variable optional. Returns undefined if not set.

const env = configEnv(process.env, {
    OPTIONAL_API_KEY: e.string().optional(),
    OPTIONAL_PORT: e.number().optional(),
    OPTIONAL_FLAG: e.boolean().optional(),
});

.default(value)

Provides a default value if the variable is not set.

const env = configEnv(process.env, {
    PORT: e.number().default(3000),
    NODE_ENV: e.string().default("development"),
    DEBUG: e.boolean().default(false),
});

Status Messages

The function provides two types of status messages:

⚠️ Warning

Default value used or optional variable not set:

Env variable DEBUG is not set, using default value: false
Optional env variable API_KEY is not set and has no default value

❌ Error

Required variable missing or parsing failed (throws error):

Missing required env variable: DATABASE_URL
Invalid number for env variable PORT: abc123

🎯 Advanced Examples

Full Application Configuration

import { configEnv, e } from "@withtahmid/safenv";

const env = configEnv(process.env, {
    // Server
    NODE_ENV: e.string().default("development"),
    PORT: e.number().default(3000),
    HOST: e.string().default("localhost"),

    // Database
    DATABASE_URL: e.string(),
    DB_POOL_SIZE: e.number().default(10),

    // Redis
    REDIS_HOST: e.string(),
    REDIS_PORT: e.number().default(6379),

    // Features
    ENABLE_CACHE: e.boolean().default(true),
    ENABLE_METRICS: e.boolean().optional(),

    // API Keys
    JWT_SECRET: e.string(),
    API_KEY: e.string(),
});

export default env;

🔍 Validation Rules

| Scenario | Modifier | Default | Result | | -------------------- | ------------- | ------------ | ------------------------- | | Value exists & valid | - | - | ✅ Success | | Value missing | - | - | ❌ Error (throws) | | Value missing | .optional() | - | ⚠️ Warning (undefined) | | Value missing | - | .default() | ⚠️ Warning (uses default) | | Value invalid format | - | - | ❌ Error (throws) |

🛠️ Best Practices

  1. Load configuration early: Import and configure env at the top of your entry file

    import { env } from "./config/env";
    // Rest of your imports...
  2. Use required for critical values: Don't use .optional() or .default() for essential config

    DATABASE_URL: e.string(), // Required, no default
  3. Provide sensible defaults: Make development easier

    PORT: e.number().default(3000),
    NODE_ENV: e.string().default("development"),
  4. Centralize configuration: Keep all env configuration in one file

    // config/env.ts
    export const env = configEnv(process.env, {
        /* ... */
    });
  5. Type everything: Leverage TypeScript's type inference

    // env.PORT is automatically typed as number
    // env.DATABASE_URL is automatically typed as string

📋 Example .env File

# Server Configuration
NODE_ENV=production
PORT=8080
HOST=0.0.0.0

# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
DB_POOL_SIZE=20

# Redis
REDIS_HOST=localhost
REDIS_PORT=6379

# Features
ENABLE_CACHE=true

# Security
JWT_SECRET=your-secret-key
API_KEY=your-api-key

🔄 Migration Guide

From dotenv

// Before
import dotenv from "dotenv";
dotenv.config();

const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000;
const DATABASE_URL = process.env.DATABASE_URL!;
// After
import { configEnv, e } from "@withtahmid/safenv";

const env = configEnv(process.env, {
    PORT: e.number().default(3000),
    DATABASE_URL: e.string(),
});