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

smart-env-plus

v1.0.1

Published

Professional environment variable validation with strict type checking for Node.js and TypeScript

Readme

smart-env

CI npm version npm downloads License

Professional environment variable validation with strict type checking for Node.js and TypeScript.

Prevent runtime errors caused by missing or invalid environment variables by validating them at boot time with comprehensive type checking and helpful error messages.

Features

  • Type-Safe: Full TypeScript support with type inference
  • Comprehensive Validation: String, number, boolean, URL, JSON, and enum types
  • Developer-Friendly: Clear error messages with suggestions
  • Zero-Config: Works out of the box with sensible defaults
  • CLI Tools: Initialize projects and validate configurations
  • Framework Agnostic: Works with Express, NestJS, Next.js, Fastify, and more
  • Package Manager Support: Works with npm, yarn, and pnpm
  • Flexible: Support for required/optional variables, defaults, and custom validation rules

Installation

# npm
npm install smart-env-plus

# yarn
yarn add smart-env-plus

# pnpm
pnpm add smart-env-plus

Quick Start

1. Initialize

# npm
npx smart-env-plus init

# yarn
yarn smart-env-plus init

# pnpm
pnpm smart-env-plus init

This creates:

  • env.config.ts - Your environment schema definition
  • .env.example - Example environment file
  • .env - Your local environment file (copied from example)

2. Define Your Schema

Edit env.config.ts:

import { createEnv } from 'smart-env';

export const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production', 'test'] as const,
    default: 'development'
  },
  PORT: {
    type: 'number',
    default: 3000
  },
  DATABASE_URL: {
    type: 'url',
    required: true
  },
  API_KEY: {
    type: 'string',
    required: true,
    minLength: 32
  }
});

3. Use in Your Application

import { env } from './env.config';

console.log(`Server running on port ${env.PORT}`);
// TypeScript knows env.PORT is a number!

app.listen(env.PORT);

4. Validate

# npm
npx smart-env-plus validate

# yarn
yarn smart-env-plus validate

# pnpm
pnpm smart-env-plus validate

API Reference

createEnv<T>(schema, options?)

Creates a typed and validated environment configuration.

Parameters:

  • schema: Environment variable schema definition
  • options (optional):
    • env: Environment object to validate (defaults to process.env)
    • throwOnError: Whether to throw on validation failure (default: true)
    • verbose: Print validation results to console (default: false)

Returns: Typed environment object

Example:

const env = createEnv({
  PORT: { type: 'number', default: 3000 },
  DATABASE_URL: { type: 'url', required: true }
});

validate(schema, env?)

Validates environment without throwing errors.

Parameters:

  • schema: Environment variable schema
  • env: Environment object (defaults to process.env)

Returns: ValidationResult with valid, errors, and warnings

Example:

import { validate, formatResult } from 'smart-env';

const result = validate({
  DATABASE_URL: { type: 'url', required: true }
});

if (!result.valid) {
  console.error(formatResult(result));
  process.exit(1);
}

Type Configuration

String

{
  type: 'string',
  required?: boolean,
  default?: string,
  minLength?: number,
  maxLength?: number,
  pattern?: RegExp,
  description?: string
}

Example:

API_KEY: {
  type: 'string',
  required: true,
  minLength: 32,
  pattern: /^sk-[a-zA-Z0-9]+$/
}

Number

{
  type: 'number',
  required?: boolean,
  default?: number,
  min?: number,
  max?: number,
  integer?: boolean,
  description?: string
}

Example:

PORT: {
  type: 'number',
  default: 3000,
  min: 1,
  max: 65535,
  integer: true
}

Boolean

{
  type: 'boolean',
  required?: boolean,
  default?: boolean,
  description?: string
}

Accepts: true, false, 1, 0, yes, no (case-insensitive)

Example:

DEBUG: {
  type: 'boolean',
  default: false
}

URL

{
  type: 'url',
  required?: boolean,
  default?: string,
  protocols?: string[],
  description?: string
}

Example:

DATABASE_URL: {
  type: 'url',
  required: true,
  protocols: ['postgresql', 'mysql']
}

JSON

{
  type: 'json',
  required?: boolean,
  default?: any,
  description?: string
}

Example:

FEATURE_FLAGS: {
  type: 'json',
  default: { newUI: false }
}

Enum

{
  type: 'enum',
  values: readonly string[],
  required?: boolean,
  default?: string,
  description?: string
}

Example:

NODE_ENV: {
  type: 'enum',
  values: ['development', 'production', 'test'] as const,
  required: true
}

CLI Commands

smart-env-plus init

Initialize smart-env in your project.

# npm
npx smart-env-plus init [options]

# yarn
yarn smart-env-plus init [options]

# pnpm
pnpm smart-env-plus init [options]

Options:
  -f, --force    Overwrite existing files

smart-env-plus validate

Validate environment variables against your schema.

# npm
npx smart-env-plus validate [options]

# yarn
yarn smart-env-plus validate [options]

# pnpm
pnpm smart-env-plus validate [options]

Options:
  -c, --config <path>    Path to env.config.ts
  -e, --env <path>       Path to .env file
  -v, --verbose          Show detailed output

smart-env-plus scan

Scan your project for process.env usage.

# npm
npx smart-env-plus scan

# yarn
yarn smart-env-plus scan

# pnpm
pnpm smart-env-plus scan

This finds all environment variable references in your codebase to help you create a complete schema.

Error Messages

smart-env provides clear, actionable error messages:

✘ Environment validation failed:

  1. DATABASE_URL
     Required environment variable is missing
     Expected: URL

  2. PORT
     Invalid number format
     Expected: number
     Received: "not-a-number"

Suggested fixes for .env:

  DATABASE_URL=<your-value-here>
  PORT=<your-value-here>

Framework Integration

Express.js

Perfect for REST APIs and web applications.

import express from 'express';
import { createEnv } from 'smart-env';

// Define environment schema
export const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production', 'test'] as const,
    default: 'development'
  },
  PORT: {
    type: 'number',
    default: 3000,
    min: 1,
    max: 65535
  },
  DATABASE_URL: {
    type: 'url',
    required: true,
    protocols: ['postgresql', 'mysql']
  },
  JWT_SECRET: {
    type: 'string',
    required: true,
    minLength: 32
  },
  CORS_ORIGINS: {
    type: 'json',
    default: ['http://localhost:3000']
  }
});

const app = express();

// Use validated environment
app.listen(env.PORT, () => {
  console.log(`🚀 Server running on port ${env.PORT}`);
  console.log(`📊 Environment: ${env.NODE_ENV}`);
  console.log(`🔗 Database: ${env.DATABASE_URL}`);
});

Next.js (Pages Router & App Router)

Handles both server-side and client-side variables with NEXT_PUBLIC_ prefix.

Setup

Create env.config.ts in your project root:

import { createEnv } from 'smart-env';

export const env = createEnv({
  // Server-side only (never exposed to browser)
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production', 'test'] as const,
    required: true
  },
  DATABASE_URL: {
    type: 'url',
    required: true,
    protocols: ['postgresql', 'mysql', 'mongodb']
  },
  NEXTAUTH_SECRET: {
    type: 'string',
    required: true,
    minLength: 32
  },
  NEXTAUTH_URL: {
    type: 'url',
    required: true
  },
  STRIPE_SECRET_KEY: {
    type: 'string',
    required: false,
    pattern: /^sk_(test|live)_/
  },

  // Client-side (exposed to browser with NEXT_PUBLIC_ prefix)
  NEXT_PUBLIC_APP_URL: {
    type: 'url',
    required: true
  },
  NEXT_PUBLIC_API_URL: {
    type: 'url',
    required: true
  },
  NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: {
    type: 'string',
    required: false,
    pattern: /^pk_(test|live)_/
  },
  NEXT_PUBLIC_ANALYTICS_ID: {
    type: 'string',
    required: false
  }
});

export type Env = typeof env;

Usage in Pages Router

// pages/index.tsx
import { env } from '../env.config';

export default function Home() {
  // ✅ Client-side variables work in components
  console.log(env.NEXT_PUBLIC_API_URL);

  return <div>Home Page</div>;
}

export async function getServerSideProps() {
  // ✅ Server-side variables work here
  const dbUrl = env.DATABASE_URL;
  const secret = env.NEXTAUTH_SECRET;

  return { props: {} };
}

// pages/api/users.ts
import { env } from '../../env.config';

export default async function handler(req, res) {
  // ✅ All server variables available in API routes
  const db = await connectDB(env.DATABASE_URL);
  const users = await db.users.findMany();
  res.json(users);
}

Usage in App Router

// app/page.tsx (Server Component)
import { env } from '../env.config';

export default async function HomePage() {
  // ✅ Server components can access ALL variables
  const db = await connectDB(env.DATABASE_URL);
  const data = await db.getData();

  return <div>Server Component</div>;
}

// app/components/ClientButton.tsx (Client Component)
'use client';
import { env } from '../../env.config';

export default function ClientButton() {
  // ✅ Only NEXT_PUBLIC_ variables work here
  const apiUrl = env.NEXT_PUBLIC_API_URL;

  const handleClick = () => {
    fetch(apiUrl + '/data').then(/* ... */);
  };

  return <button onClick={handleClick}>Fetch Data</button>;
}

// app/api/users/route.ts (Route Handler)
import { env } from '../../../env.config';

export async function GET() {
  const db = await connectDB(env.DATABASE_URL);
  const users = await db.users.findMany();
  return Response.json(users);
}

Middleware

// middleware.ts
import { env } from './env.config';
import { NextResponse } from 'next/server';

export function middleware(request) {
  // ✅ Access server-side env vars in middleware
  console.log('Auth URL:', env.NEXTAUTH_URL);
  return NextResponse.next();
}

Build-time Validation

Update your package.json:

{
  "scripts": {
    "dev": "next dev",
    "build": "smart-env-plus validate && next build",
    "start": "next start"
  }
}

Then run with your preferred package manager:

# npm
npm run build

# yarn
yarn build

# pnpm
pnpm build

This ensures environment errors are caught at build time!

.env.local Example

# Server-only variables
NODE_ENV=development
DATABASE_URL=postgresql://localhost:5432/myapp
NEXTAUTH_SECRET=your-secret-key-here-minimum-32-characters
NEXTAUTH_URL=http://localhost:3000
STRIPE_SECRET_KEY=sk_test_xxxxx

# Client-side variables (exposed to browser)
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:3000/api
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
NEXT_PUBLIC_ANALYTICS_ID=G-XXXXXXXXXX

NestJS

Integrates seamlessly with NestJS's configuration module.

// env.config.ts
import { createEnv } from 'smart-env';

export const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production', 'test'] as const,
    default: 'development'
  },
  PORT: {
    type: 'number',
    default: 3000
  },
  DATABASE_URL: {
    type: 'url',
    required: true
  },
  JWT_SECRET: {
    type: 'string',
    required: true,
    minLength: 32
  },
  JWT_EXPIRY: {
    type: 'string',
    default: '24h',
    pattern: /^\d+[smhd]$/
  },
  REDIS_URL: {
    type: 'url',
    required: false,
    protocols: ['redis']
  }
});

// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { env } from './env.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validate: () => env  // Use smart-env for validation
    })
  ],
  // ... other modules
})
export class AppModule {}

// database.service.ts
import { Injectable } from '@nestjs/common';
import { env } from './env.config';

@Injectable()
export class DatabaseService {
  connect() {
    // ✅ Type-safe environment access
    return connectDB(env.DATABASE_URL);
  }
}

Fastify

Works great with Fastify's plugin system.

import Fastify from 'fastify';
import { createEnv } from 'smart-env';

const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production'] as const,
    default: 'development'
  },
  PORT: {
    type: 'number',
    default: 3000
  },
  HOST: {
    type: 'string',
    default: '0.0.0.0'
  },
  LOG_LEVEL: {
    type: 'enum',
    values: ['fatal', 'error', 'warn', 'info', 'debug', 'trace'] as const,
    default: 'info'
  },
  DATABASE_URL: {
    type: 'url',
    required: true
  }
});

const fastify = Fastify({
  logger: {
    level: env.LOG_LEVEL
  }
});

// Register routes
fastify.get('/', async (request, reply) => {
  return {
    status: 'ok',
    env: env.NODE_ENV
  };
});

// Start server
fastify.listen({
  port: env.PORT,
  host: env.HOST
}, (err) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
});

Remix

Perfect for full-stack Remix applications.

// env.server.ts
import { createEnv } from 'smart-env';

export const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'production', 'test'] as const,
    required: true
  },
  DATABASE_URL: {
    type: 'url',
    required: true
  },
  SESSION_SECRET: {
    type: 'string',
    required: true,
    minLength: 32
  }
});

// app/routes/index.tsx
import { json, type LoaderFunction } from '@remix-run/node';
import { env } from '~/env.server';

export const loader: LoaderFunction = async () => {
  // ✅ Access validated environment in loaders
  const db = await connectDB(env.DATABASE_URL);
  const data = await db.getData();

  return json({ data });
};

Vite + React/Vue/Svelte

For frontend applications built with Vite.

// env.config.ts
import { createEnv } from 'smart-env';

export const env = createEnv({
  // Vite exposes variables prefixed with VITE_
  VITE_API_URL: {
    type: 'url',
    required: true
  },
  VITE_APP_TITLE: {
    type: 'string',
    default: 'My App'
  },
  VITE_ENABLE_ANALYTICS: {
    type: 'boolean',
    default: false
  }
}, {
  env: import.meta.env  // Use Vite's import.meta.env
});

// App.tsx / App.vue / App.svelte
import { env } from './env.config';

function App() {
  // ✅ Type-safe access to environment
  const apiUrl = env.VITE_API_URL;

  return <div>{env.VITE_APP_TITLE}</div>;
}

Docker Integration

Validate environment at build time:

FROM node:18-alpine
WORKDIR /app

# Copy package files (supports npm, yarn, or pnpm)
COPY package*.json ./
# COPY yarn.lock ./    # Uncomment if using yarn
# COPY pnpm-lock.yaml ./    # Uncomment if using pnpm

# Install dependencies (choose one)
RUN npm ci
# RUN yarn install --frozen-lockfile    # For yarn
# RUN pnpm install --frozen-lockfile    # For pnpm

COPY . .

# Validate environment during build
RUN npx smart-env-plus validate || exit 1

RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]

CI/CD Integration

Add validation to your CI pipeline:

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          cache: 'npm'    # or 'yarn' or 'pnpm'

      # Using npm
      - run: npm ci
      - run: npx smart-env-plus validate
      - run: npm test

      # Or using yarn
      # - run: yarn install --frozen-lockfile
      # - run: yarn smart-env-plus validate
      # - run: yarn test

      # Or using pnpm
      # - run: pnpm install --frozen-lockfile
      # - run: pnpm smart-env-plus validate
      # - run: pnpm test

Common Use Cases

Authentication (NextAuth / Passport)

export const env = createEnv({
  // NextAuth configuration
  NEXTAUTH_SECRET: {
    type: 'string',
    required: true,
    minLength: 32,
    description: 'Secret for JWT encryption'
  },
  NEXTAUTH_URL: {
    type: 'url',
    required: true
  },

  // OAuth providers
  GITHUB_CLIENT_ID: {
    type: 'string',
    required: false
  },
  GITHUB_CLIENT_SECRET: {
    type: 'string',
    required: false
  },
  GOOGLE_CLIENT_ID: {
    type: 'string',
    required: false
  },
  GOOGLE_CLIENT_SECRET: {
    type: 'string',
    required: false
  }
});

Payment Processing (Stripe)

export const env = createEnv({
  // Server-side (secrets)
  STRIPE_SECRET_KEY: {
    type: 'string',
    required: true,
    pattern: /^sk_(test|live)_/,
    description: 'Stripe secret key'
  },
  STRIPE_WEBHOOK_SECRET: {
    type: 'string',
    required: true,
    pattern: /^whsec_/,
    description: 'Stripe webhook signing secret'
  },

  // Client-side (public keys)
  NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: {
    type: 'string',
    required: true,
    pattern: /^pk_(test|live)_/
  }
});

Email Services (SendGrid / Resend)

export const env = createEnv({
  // SendGrid
  SENDGRID_API_KEY: {
    type: 'string',
    required: false,
    pattern: /^SG\./
  },
  SENDGRID_FROM_EMAIL: {
    type: 'string',
    required: false,
    pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  },

  // Resend
  RESEND_API_KEY: {
    type: 'string',
    required: false,
    pattern: /^re_/
  }
});

Database Connections

export const env = createEnv({
  // Primary database
  DATABASE_URL: {
    type: 'url',
    required: true,
    protocols: ['postgresql', 'mysql', 'mongodb']
  },

  // Read replica (optional)
  DATABASE_REPLICA_URL: {
    type: 'url',
    required: false,
    protocols: ['postgresql', 'mysql']
  },

  // Connection pool settings
  DATABASE_POOL_MIN: {
    type: 'number',
    default: 2,
    min: 1
  },
  DATABASE_POOL_MAX: {
    type: 'number',
    default: 10,
    min: 1,
    max: 100
  },

  // Redis cache
  REDIS_URL: {
    type: 'url',
    required: false,
    protocols: ['redis', 'rediss']
  }
});

Analytics & Monitoring

export const env = createEnv({
  // Server-side monitoring
  SENTRY_DSN: {
    type: 'url',
    required: false
  },
  SENTRY_AUTH_TOKEN: {
    type: 'string',
    required: false
  },

  // Client-side analytics
  NEXT_PUBLIC_GA_MEASUREMENT_ID: {
    type: 'string',
    required: false,
    pattern: /^G-/
  },
  NEXT_PUBLIC_POSTHOG_KEY: {
    type: 'string',
    required: false
  },
  NEXT_PUBLIC_MIXPANEL_TOKEN: {
    type: 'string',
    required: false
  }
});

AI/ML APIs (OpenAI, Anthropic)

export const env = createEnv({
  // OpenAI
  OPENAI_API_KEY: {
    type: 'string',
    required: false,
    pattern: /^sk-/,
    minLength: 40
  },
  OPENAI_ORG_ID: {
    type: 'string',
    required: false
  },

  // Anthropic
  ANTHROPIC_API_KEY: {
    type: 'string',
    required: false,
    pattern: /^sk-ant-/
  },

  // Model configuration
  AI_MODEL: {
    type: 'enum',
    values: ['gpt-4', 'gpt-3.5-turbo', 'claude-3-opus', 'claude-3-sonnet'] as const,
    default: 'gpt-3.5-turbo'
  },
  AI_MAX_TOKENS: {
    type: 'number',
    default: 1000,
    min: 1,
    max: 4000
  }
});

File Storage (S3, Cloudflare R2)

export const env = createEnv({
  // AWS S3
  AWS_ACCESS_KEY_ID: {
    type: 'string',
    required: false
  },
  AWS_SECRET_ACCESS_KEY: {
    type: 'string',
    required: false
  },
  AWS_REGION: {
    type: 'string',
    default: 'us-east-1'
  },
  AWS_S3_BUCKET: {
    type: 'string',
    required: false
  },

  // Cloudflare R2
  R2_ACCOUNT_ID: {
    type: 'string',
    required: false
  },
  R2_ACCESS_KEY_ID: {
    type: 'string',
    required: false
  },
  R2_SECRET_ACCESS_KEY: {
    type: 'string',
    required: false
  }
});

Feature Flags

export const env = createEnv({
  // Server-side feature flags
  ENABLE_EXPERIMENTAL_FEATURES: {
    type: 'boolean',
    default: false
  },
  ENABLE_PREMIUM_FEATURES: {
    type: 'boolean',
    default: false
  },
  MAINTENANCE_MODE: {
    type: 'boolean',
    default: false
  },

  // Client-side feature flags
  NEXT_PUBLIC_ENABLE_NEW_UI: {
    type: 'boolean',
    default: false
  },
  NEXT_PUBLIC_ENABLE_BETA_FEATURES: {
    type: 'boolean',
    default: false
  }
});

Multi-Environment Configuration

export const env = createEnv({
  NODE_ENV: {
    type: 'enum',
    values: ['development', 'staging', 'production', 'test'] as const,
    required: true
  },

  // Environment-specific URLs
  APP_URL: {
    type: 'url',
    required: true
  },
  API_URL: {
    type: 'url',
    required: true
  },

  // Feature flags per environment
  ENABLE_DEBUG_LOGGING: {
    type: 'boolean',
    default: false  // true in development, false in production
  },
  RATE_LIMIT_PER_MINUTE: {
    type: 'number',
    default: 100,  // Lower in production, higher in development
    min: 1
  }
});

Testing

Test with custom environments:

import { createEnv } from 'smart-env';
import { describe, it, expect } from 'vitest';

describe('App configuration', () => {
  it('should load test environment', () => {
    const env = createEnv(
      {
        DATABASE_URL: { type: 'url', required: true },
        API_KEY: { type: 'string', required: true }
      },
      {
        env: {
          DATABASE_URL: 'postgresql://localhost:5432/test',
          API_KEY: 'test-key-123'
        }
      }
    );

    expect(env.DATABASE_URL).toBe('postgresql://localhost:5432/test');
    expect(env.API_KEY).toBe('test-key-123');
  });

  it('should validate types correctly', () => {
    expect(() => {
      createEnv(
        { PORT: { type: 'number', required: true } },
        { env: { PORT: 'not-a-number' } }
      );
    }).toThrow('Environment validation failed');
  });

  it('should use default values', () => {
    const env = createEnv(
      { DEBUG: { type: 'boolean', default: false } },
      { env: {} }
    );

    expect(env.DEBUG).toBe(false);
  });
});

Best Practices

  1. Define all environment variables in your schema - Don't use process.env directly
  2. Use required: true for critical variables - Fail fast on startup
  3. Provide sensible defaults - Make local development easier
  4. Add descriptions - Document what each variable does
  5. Use strict types - Prefer enum over string when possible
  6. Validate in CI/CD - Catch configuration errors before deployment
  7. Keep secrets secret - Never commit .env files

Package Manager Support

smart-env-plus works seamlessly with all major Node.js package managers:

npm

npm install smart-env-plus
npx smart-env-plus init

Yarn (v1, v2, v3+)

yarn add smart-env-plus
yarn smart-env-plus init

pnpm

pnpm add smart-env-plus
pnpm smart-env-plus init

All package managers support the same CLI commands and features!

TypeScript Support

smart-env provides full type inference:

const env = createEnv({
  PORT: { type: 'number', default: 3000 },
  NODE_ENV: { type: 'enum', values: ['dev', 'prod'] as const }
});

// TypeScript knows these types:
env.PORT;      // number
env.NODE_ENV;  // 'dev' | 'prod'

Migration Guide

From dotenv

// Before
require('dotenv').config();
const port = parseInt(process.env.PORT || '3000');

// After
import { env } from './env.config';
const port = env.PORT; // Already a number with default 3000

Installation:

# npm
npm uninstall dotenv
npm install smart-env-plus

# yarn
yarn remove dotenv
yarn add smart-env-plus

# pnpm
pnpm remove dotenv
pnpm add smart-env-plus

From envalid

// Before
import { cleanEnv, port, str } from 'envalid';
const env = cleanEnv(process.env, {
  PORT: port({ default: 3000 }),
  API_KEY: str()
});

// After
import { createEnv } from 'smart-env';
const env = createEnv({
  PORT: { type: 'number', default: 3000 },
  API_KEY: { type: 'string', required: true }
});

Installation:

# npm
npm uninstall envalid
npm install smart-env-plus

# yarn
yarn remove envalid
yarn add smart-env-plus

# pnpm
pnpm remove envalid
pnpm add smart-env-plus

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

MIT

Support