{"id":50746387,"url":"https://github.com/mzeeshanwahid/next-safe-env","last_synced_at":"2026-06-10T21:31:11.677Z","repository":{"id":354419173,"uuid":"1223537290","full_name":"mzeeshanwahid/next-safe-env","owner":"mzeeshanwahid","description":"Typed, validated environment variables for Next.js and Node.js","archived":false,"fork":false,"pushed_at":"2026-05-06T16:09:31.000Z","size":915,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T18:17:10.301Z","etag":null,"topics":["configuration","dotenv","edge-runtime","env-validation","environment-variables","next-publix","nextjs","nodejs","server-only","type-safe","typescript","vite","zero-dependency"],"latest_commit_sha":null,"homepage":"https://next-safe-env.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mzeeshanwahid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-28T12:20:40.000Z","updated_at":"2026-05-06T16:09:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mzeeshanwahid/next-safe-env","commit_stats":null,"previous_names":["mzeeshanwahid/next-safe-env"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/mzeeshanwahid/next-safe-env","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzeeshanwahid%2Fnext-safe-env","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzeeshanwahid%2Fnext-safe-env/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzeeshanwahid%2Fnext-safe-env/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzeeshanwahid%2Fnext-safe-env/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mzeeshanwahid","download_url":"https://codeload.github.com/mzeeshanwahid/next-safe-env/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzeeshanwahid%2Fnext-safe-env/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34172196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","dotenv","edge-runtime","env-validation","environment-variables","next-publix","nextjs","nodejs","server-only","type-safe","typescript","vite","zero-dependency"],"created_at":"2026-06-10T21:31:10.988Z","updated_at":"2026-06-10T21:31:11.671Z","avatar_url":"https://github.com/mzeeshanwahid.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/mzeeshanwahid/next-safe-env/main/assets/logo-nobg.png\" width=\"400\" alt=\"next-safe-env logo\" /\u003e\n  \u003ch1\u003enext-safe-env\u003c/h1\u003e\n  \u003cp\u003eTyped, validated environment variables for Next.js and Node.js. Crash at startup, never at runtime.\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://www.npmjs.com/package/next-safe-env\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/next-safe-env?color=0ea5e9\u0026label=npm\" alt=\"npm version\" /\u003e\u003c/a\u003e \u003ca href=\"https://bundlephobia.com/package/next-safe-env\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/minzip/next-safe-env?color=22c55e\u0026label=gzipped\" alt=\"bundle size\" /\u003e\u003c/a\u003e \u003ca href=\"./LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/next-safe-env?color=a855f7\" alt=\"license\" /\u003e\u003c/a\u003e \u003ca href=\"https://github.com/mzeeshanwahid/next-safe-env/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/mzeeshanwahid/next-safe-env/ci.yml?label=tests\" alt=\"tests\" /\u003e\u003c/a\u003e \u003ca href=\"./package.json\"\u003e\u003cimg src=\"https://img.shields.io/badge/dependencies-zero-f97316\" alt=\"zero dependencies\" /\u003e\u003c/a\u003e \u003ca href=\"https://www.typescriptlang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/TypeScript-5.x-3178c6\" alt=\"TypeScript\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\n---\n\n## The Problem\n\nEvery Next.js and Node.js project has the same boilerplate:\n\n```ts\nconst DATABASE_URL = process.env.DATABASE_URL\nif (!DATABASE_URL) throw new Error('Missing DATABASE_URL')\n\nconst PORT = parseInt(process.env.PORT ?? '3000', 10)\nif (isNaN(PORT)) throw new Error('PORT must be a number')\n```\n\n`process.env.X` is always `string | undefined` - no types, no autocomplete. Missing or malformed vars surface mid-request, not at startup. Nothing stops you from reading a server secret in a client component and getting a silent `undefined` in the browser. Every project re-writes the same validation logic with no single place to audit what the app needs to run.\n\n`next-safe-env` fixes all of this with a single function call.\n\n---\n\n## Why `next-safe-env`?\n\n| Feature | **next-safe-env** | t3-env | envalid | dotenv + Zod |\n|---|:---:|:---:|:---:|:---:|\n| Zero dependencies | ✅ | ❌ | ❌ | ❌ |\n| Next.js App Router support | ✅ | Partial | ❌ | ❌ |\n| Server/client TypeScript split | ✅ | ✅ | ❌ | Manual |\n| Edge Runtime adapter | ✅ | ❌ | ❌ | ❌ |\n| Fluent validator API | ✅ | Schema-based | Custom | Schema-based |\n| Pretty error output | ✅ | Partial | ✅ | Manual |\n| Bundle size | **\u003c 5 kB** | ~50 kB+ | ~10 kB | ~50 kB+ |\n| Auto-enforce `NEXT_PUBLIC_` prefix | ✅ | Manual | ❌ | ❌ |\n| Zod interop | Optional ✅ | Required | ❌ | Required |\n| `ClientEnv\u003cT\u003e` server-only branding | ✅ | Partial | ❌ | Manual |\n| Vite adapter | ✅ | ✅ | ❌ | Manual |\n| CLI (`check` / `init`) | ✅ | ❌ | ❌ | ❌ |\n\nIf your project already uses a schema validation library, tools like `t3-env` or `envalid` integrate well with your existing setup. `next-safe-env` is for teams that want typed, validated env vars with no additional dependencies - the full feature set ships in under 5 kB.\n\n---\n\n## Requirements\n\n- **Node.js** 18+\n- **TypeScript** 5.x\n\nNo runtime dependencies.\n\n---\n\n## Installation\n\n```bash\nnpm install next-safe-env\n# or\npnpm add next-safe-env\n# or\nyarn add next-safe-env\n```\n\n\u003e `next-safe-env` validates what is already in `process.env`. It does not load `.env` files. For that, use Next.js's built-in `.env` support or `dotenv`.\n\n---\n\n## Quick Start\n\n```ts\n// src/env.ts\nimport { createEnv, str, url, port, bool } from 'next-safe-env'\n\nexport const env = createEnv({\n  server: {\n    DATABASE_URL: url(),                // must be a valid URL\n    PORT:         port().default(3000), // coerced to number, defaults to 3000\n    NODE_ENV:     str().enum(['development', 'production', 'test']),\n  },\n  client: {\n    NEXT_PUBLIC_APP_NAME:     str().default('My App'),\n    NEXT_PUBLIC_ENABLE_DEBUG: bool().default(false),\n  },\n  runtimeEnv: {\n    DATABASE_URL:             process.env.DATABASE_URL,\n    PORT:                     process.env.PORT,\n    NODE_ENV:                 process.env.NODE_ENV,\n    NEXT_PUBLIC_APP_NAME:     process.env.NEXT_PUBLIC_APP_NAME,\n    NEXT_PUBLIC_ENABLE_DEBUG: process.env.NEXT_PUBLIC_ENABLE_DEBUG,\n  },\n})\n```\n\n```ts\n// anywhere in your app\nimport { env } from '@/env'\n\nenv.DATABASE_URL          // string\nenv.PORT                  // number - not string\nenv.NEXT_PUBLIC_APP_NAME  // string\n```\n\nIf any variable is missing or invalid, the app refuses to start and prints every problem at once:\n\n```\n[next-safe-env] Environment validation failed - 3 error(s):\n\n  ✗ DATABASE_URL  - Required. Expected a valid URL. Got: \"postgres-localhost\"\n  ✗ JWT_SECRET    - Too short. Must be ≥ 32 characters. Got length: 12\n  ✗ SMTP_PORT     - Invalid port. Must be 1–65535. Got: \"99999\"\n```\n\n---\n\n## CLI\n\n`next-safe-env` ships a zero-install CLI for validation and scaffolding.\n\n### `check` — validate before you deploy\n\nImports your compiled env file in an isolated process and exits `0` if all vars are valid, `1` if any fail. Drop it into any CI pipeline to gate deployments:\n\n```bash\n# Auto-discovers src/env.js then dist/env.js\nnpx next-safe-env check\n\n# Or point at a specific file\nnpx next-safe-env check ./dist/env.js\n```\n\n```\n[next-safe-env] Checking src/env.js...\n\n[next-safe-env] Environment validation failed — 2 error(s):\n\n  ✗ DATABASE_URL  — Expected valid URL. Got: \"postgres-localhost\"\n  ✗ JWT_SECRET    — Expected length \u003e= 32. Got length: 12\n\n[next-safe-env] ✗ Validation failed.\n```\n\n### `init` — generate `src/env.ts` and `.env.example`\n\nAn interactive scaffold that asks which variables your app needs, their types, defaults, and constraints — then writes a ready-to-use `env.ts` and a commented `.env.example`:\n\n```bash\nnpx next-safe-env init\n\n# Custom output path\nnpx next-safe-env init --output config/env.ts\n```\n\nThe generated `.env.example` includes inline comments for every variable so new contributors know exactly what to fill in:\n\n```dotenv\n# DATABASE_URL — required valid URL\nDATABASE_URL=\n\n# PORT — required port number (1–65535)\n# Default: 3000\nPORT=3000\n\n# NODE_ENV — required string\n# Allowed values: development | production | test\nNODE_ENV=\n```\n\n---\n\n## Documentation\n\nThe full documentation is available at **[next-safe-env.dev](https://next-safe-env.dev)**.\n\n### Guides\n\n- [Getting Started](https://next-safe-env.dev/quickstart) - Install and validate your first env var in minutes\n- [Next.js App Router](https://next-safe-env.dev/guides/nextjs) - Server/client splitting with automatic `NEXT_PUBLIC_` enforcement\n- [Node.js](https://next-safe-env.dev/guides/nodejs) - Plain Node.js servers, APIs, and CLI scripts\n- [Edge Runtime](https://next-safe-env.dev/guides/edge-runtime) - Vercel Edge Runtime and Next.js Middleware\n- [Vite](https://next-safe-env.dev/guides/vite) - Non-Next.js React apps with `import.meta.env`\n- [Zod Interop](https://next-safe-env.dev/guides/zod-interop) - Pass `z.object(...)` schemas directly, no rewrites needed\n- [Testing](https://next-safe-env.dev/guides/testing) - Skip validation in test environments without removing your schema\n- [CLI](https://next-safe-env.dev/guides/cli) - `check` and `init` commands for CI validation and interactive scaffolding\n\n### API Reference\n\n- [Validators](https://next-safe-env.dev/api/validators) - `str`, `num`, `bool`, `url`, `port` and their chainable rules\n- [createEnv()](https://next-safe-env.dev/api/create-env) - Full reference for every configuration option\n- [TypeScript Types](https://next-safe-env.dev/api/types) - `ServerOnly\u003cT\u003e`, `ClientEnv\u003cT\u003e`, and all exported types\n\n### Concepts\n\n- [Adapters](https://next-safe-env.dev/concepts/adapters) - How Next.js, Node.js, Edge Runtime, and Vite adapters work\n- [Server \u0026 Client Split](https://next-safe-env.dev/concepts/server-client-split) - How env vars are separated and protected per runtime context\n- [Error Handling](https://next-safe-env.dev/concepts/error-handling) - Validation errors, pretty output, and custom error handlers\n\n---\n\n`next-safe-env` was built because `process.env.X` should never be `string | undefined` in a typed codebase - and getting full validation, type inference, and Next.js adapter support shouldn't require adding new dependencies to do it.\n\nMIT © 2026\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmzeeshanwahid%2Fnext-safe-env","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmzeeshanwahid%2Fnext-safe-env","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmzeeshanwahid%2Fnext-safe-env/lists"}