Type-safe env variables with Zod
By Dmytro Laptiev • October 15, 2025

Best practices
Hello folks 👋
Let’s talk about something simple but important — environment variables.
They control everything from your database URL to your app’s behavior in different environments.
But here’s the catch:
Environment variables are always strings and often undefined.
That means you can easily end up with unexpected bugs — like using a string instead of a number or missing a required variable.
Let’s fix that with Zod 💪
Step 1: Define a Schema
With Zod, we can describe what our environment variables should look like and automatically validate them at runtime.
import { z } from 'zod'
const envSchema = z.object({
PORT: z.coerce.number().min(1000).default(3000),
ENV: z
.union([z.literal('development'), z.literal('testing'), z.literal('production')])
.default('development'),
})
export const env = envSchema.parse(process.env)Step 2: Parse and Use It
Now when we created a env.ts file we can easily use environment variables.
import { env } from 'env'
console.log(env.PORT);