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

next-env-guard

v0.0.1

Published

Type-safe and validated environment variable manager for Next.js

Readme

next-env-guard

Type-safe and validated environment variable manager for Next.js.

Features

  • Type Safety: Full TypeScript support with automatic type inference from Zod schemas
  • Validation: Built-in validation using Zod with detailed error messages
  • Runtime Client Env: Solve the build-time vs runtime problem for client-side variables
  • Server/Client Separation: Strict enforcement of server vs client environment variables
  • Next.js Integration: Works seamlessly with App Router and Pages Router
  • Security: Prevents accidental exposure of server-side secrets to the client

Installation

npm install next-env-guard zod
# or
pnpm add next-env-guard zod
# or
yarn add next-env-guard zod

Quick Start

1. Define your environment schema

Create env.mjs in your project root:

import { createEnv } from 'next-env-guard';
import { z } from 'zod';

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    GITHUB_API_KEY: z.string().min(1),
  },
  client: {
    NEXT_PUBLIC_API_URL: z.string().url(),
  },
  runtimeEnv: process.env,
});

2. Add PublicEnvScript to your layout

For App Router (app/layout.tsx):

import { PublicEnvScript } from 'next-env-guard/script';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <PublicEnvScript />
      </head>
      <body>{children}</body>
    </html>
  );
}

For Pages Router (pages/_document.tsx):

import { Html, Head, Main, NextScript } from 'next/document';
import { PublicEnvScript } from 'next-env-guard/script';

export default function Document() {
  return (
    <Html>
      <Head>
        <PublicEnvScript />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

3. Use environment variables

In server components or API routes:

import { env } from '@/env';

// Type-safe access - no need for type assertions!
const dbUrl = env.DATABASE_URL; // string, not string | undefined

In client components:

'use client';

import { env } from '@/env';

// This will be the runtime value, not build-time!
const apiUrl = env.NEXT_PUBLIC_API_URL;

Advanced Usage

Optional Variables

export const env = createEnv({
  server: {
    REQUIRED: z.string(),
    OPTIONAL: z.string().optional(),
  },
  runtimeEnv: process.env,
});

Default Values

export const env = createEnv({
  server: {
    PORT: z.string().default('3000'),
  },
  runtimeEnv: process.env,
});

Type Coercion

export const env = createEnv({
  server: {
    PORT: z.string().transform(Number),
    ENABLED: z.string().transform((val) => val === 'true'),
  },
  runtimeEnv: process.env,
});

Complex Validation

import { z } from 'zod';

export const env = createEnv({
  server: {
    PORT: z
      .string()
      .regex(/^\d+$/, 'Must be a number')
      .transform(Number)
      .pipe(z.number().int().min(1).max(65535)),
  },
  runtimeEnv: process.env,
});

CLI Tool

Validate your environment variables without starting the server:

npx next-env-guard-validate

Options:

  • --schema <path>: Path to env.mjs file (default: ./env.mjs)
  • --format <json|human>: Output format (default: human)
  • --help: Show help message

Security

  • Server-side environment variables are never exposed to the client
  • Attempting to access server variables on the client will throw a runtime error
  • Client variables must be prefixed with NEXT_PUBLIC_
  • All values are sanitized before injection to prevent XSS attacks

How It Works

  1. Schema Definition: You define your environment variable schema using Zod
  2. Validation: Variables are validated at startup (server) or when window.__ENV is available (client)
  3. Runtime Injection: The PublicEnvScript component injects client variables into window.__ENV at runtime
  4. Type-Safe Access: The env object provides type-safe access with full IntelliSense support

Performance

This package is optimized for production use:

  • Runtime detection is cached after first call (no repeated checks)
  • Proxy handlers are optimized with minimal overhead
  • Validation is batched for better error messages
  • Bundle size: < 10KB gzipped
  • Zero runtime overhead except for initial validation

Security

  • Server variables are never exposed to the client
  • Client variables are sanitized using JSON.stringify to prevent XSS
  • Automatic security checks prevent accessing server vars on client
  • Strict validation ensures only valid values are used

Troubleshooting

window.__ENV is not available

Make sure you've added <PublicEnvScript /> to your root layout's <head> section.

Type errors with environment variables

Ensure your schema types match your usage. Use Zod's type coercion (.transform()) for number/boolean conversion.

Runtime values not updating

Client-side environment variables are injected at runtime via PublicEnvScript. Make sure the script is included in your layout.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Migration Guides

From dotenv

  1. Define your schema in env.mjs
  2. Replace process.env.* with env.* throughout your codebase
  3. TypeScript will help you find all the places to update!

From next-runtime-env

  1. Replace RuntimeEnvProvider with PublicEnvScript in your layout
  2. Replace getEnv() calls with env.* property access
  3. Define your schema with Zod validation

Requirements

  • Next.js 12+
  • React 18+
  • Node.js 18+
  • TypeScript 5+ (recommended)

License

MIT