.env to Zod & T3 Env Schema Generator
Convert .env files into Zod v4, Zod v3, or @t3-oss/env-nextjs schemas in your browser. Infers types without exposing secret values and generates .env.example.
Example Output (.env to Zod & T3 Env)
# Server & Database Configuration (Dummy Sample Values)
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://db_user:dummy_password@localhost:5432/app_dev
REDIS_URL=redis://localhost:6379
STRIPE_SECRET_KEY=sk_live_dummy_key_val
STRIPE_WEBHOOK_SECRET=whsec_dummy_secret_val
ENABLE_RATE_LIMIT=true
ADMIN_EMAIL=ops@example.com
OPTIONAL_SENTRY_DSN=
# Next.js Public Client Variables
NEXT_PUBLIC_APP_URL=https://app.example.com
NEXT_PUBLIC_ENABLE_ANALYTICS=false// Target: Zod v4 (Stable) — Values scrubbed, only types inferred
import { z } from "zod";
export const envSchema = z.object({
/** Server & Database Configuration (Dummy Sample Values) */
NODE_ENV: z.enum(["development", "production", "test"]),
PORT: z.coerce.number().int().positive(),
DATABASE_URL: z.url(),
REDIS_URL: z.url(),
/** ⚠️ Sensitive — never log or expose to client bundles */
STRIPE_SECRET_KEY: z.string().min(1),
/** ⚠️ Sensitive — never log or expose to client bundles */
STRIPE_WEBHOOK_SECRET: z.string().min(1),
ENABLE_RATE_LIMIT: z.stringbool(),
ADMIN_EMAIL: z.email(),
OPTIONAL_SENTRY_DSN: z.string().optional(),
/** Next.js Public Client Variables */
NEXT_PUBLIC_APP_URL: z.url(),
NEXT_PUBLIC_ENABLE_ANALYTICS: z.stringbool(),
});
export type Env = z.infer<typeof envSchema>;
export const env = envSchema.parse(process.env);
Understanding the .env to Zod & T3 Env Transformation
Environment variables in Node.js and Next.js are always loaded from .env files as raw strings (or undefined when missing). Relying on unvalidated process.env access scatters string-to-number and string-to-boolean conversions across your codebase and risks runtime failures when a required secret or connection string is missing in production. Generating a strict Zod v4, Zod v3, or @t3-oss/env-nextjs schema validates your configuration at application startup while keeping raw secret values completely out of your source code.
Key Architectural Benefits
- •Zero secret exposure: The engine inspects value patterns locally in your browser to infer types (URLs, ports, booleans, emails) and never prints raw secret values in the generated code.
- •Eliminates the repetitive @t3-oss/env-nextjs boilerplate of declaring every variable across server, client, and runtimeEnv blocks.
- •Prevents the classic JavaScript Boolean('false') === true bug by using z.stringbool() in Zod v4 or strict enum transforms in Zod v3.
- •Flags accidental NEXT_PUBLIC_ secret leaks (such as NEXT_PUBLIC_STRIPE_SECRET_KEY) before they are bundled into browser JavaScript.
Common Conversion Pitfalls & Fixes
Verified Edge Cases & Complex Scenarios
Real payloads often contain edge cases that break naive generators. Here is how our engine handles them:
Database and cache URLs use custom URI schemes rather than http:// or https://, which naive regex matchers misclassify as plain strings.
DATABASE_URL=postgresql://user:pass@localhost:5432/prod
REDIS_URL=redis://127.0.0.1:6379
EMPTY_OPTIONAL_KEY=export const envSchema = z.object({
DATABASE_URL: z.url(),
REDIS_URL: z.url(),
EMPTY_OPTIONAL_KEY: z.string().optional(),
});Shell-compatible .env files often prefix variables with `export`, include `#` characters inside quoted passwords, or span PEM keys across multiple lines.
export API_PORT=8080 # inline comment
REDIS_PASSWORD="p@ss#word#with#hash"
JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC
-----END PRIVATE KEY-----"export const envSchema = z.object({
API_PORT: z.coerce.number().int().positive(),
/** ⚠️ Sensitive — never log or expose to client bundles */
REDIS_PASSWORD: z.string().min(1),
/** ⚠️ Sensitive — never log or expose to client bundles */
JWT_PRIVATE_KEY: z.string().min(1),
});Prefixing a sensitive API key or webhook secret with NEXT_PUBLIC_ causes Next.js to inline the secret directly into public client JavaScript bundles.
NEXT_PUBLIC_APP_URL=https://castov.com
NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_0000000000// ⚠️ PUBLIC SECRET WARNING (NEXT_PUBLIC_STRIPE_SECRET_KEY): Variables prefixed with NEXT_PUBLIC_ are inlined into client-side JavaScript bundles!
export const envSchema = z.object({
NEXT_PUBLIC_APP_URL: z.url(),
/** ⚠️ SECURITY WARNING: NEXT_PUBLIC_ exposes 'NEXT_PUBLIC_STRIPE_SECRET_KEY' to browser bundles! */
NEXT_PUBLIC_STRIPE_SECRET_KEY: z.string().min(1),
});Frequently Asked Questions
Are my .env secret values ever sent to a server or included in the output?
Why does z.coerce.boolean() fail on 'false' in .env files?
What is the difference between runtimeEnv and experimental__runtimeEnv in @t3-oss/env-nextjs?
How can I generate a clean .env.example file to commit to Git?
Related Developer Converters
Browse AllJSON to Zod Schema
Convert raw JSON into strict, production-ready Zod schemas. Supports ISO datetime offsets, email, URLs, nullish options, and inferred TypeScript types in browser.
JSON to TypeScript
Convert JSON payloads into clean TypeScript interfaces or type aliases in browser. Extracts nested interfaces, merges optional array keys, and handles readonly modifiers.
YAML to JSON
Convert YAML configurations, Kubernetes manifests, and Docker Compose files to JSON in browser. Resolves anchors/aliases, multi-document streams, and YAML 1.2 vs 1.1 scalars.
SQL to Prisma Schema
Convert PostgreSQL and MySQL CREATE TABLE DDL statements into Prisma ORM models. Infers 1:1, 1:n, and n:m relations, enums, @default, @unique, and @@index.