0Pricing
TypeScript Academy · Lesson

Env typing and config

Validate and type environment variables; expose safe client vars with NEXT_PUBLIC; centralize config for server and client.

Intro

Goal: Centralize validated environment variables and keep types in sync. You will parse process.env with zod, export a typed env object, and expose only NEXT_PUBLIC_* to the client.

  • Runtime validation
  • Server vs client exposure
  • Single source of truth

Schemas & parser

Create separate schemas for server and client. Fail fast on invalid config during boot.

// app/lib/env.ts
import { z } from "zod"

const serverSchema = z.object({
  NODE_ENV: z.enum(["development", "test", "production"]),
  DATABASE_URL: z.string().url(),
  API_SECRET: z.string().min(1)
})

const clientSchema = z.object({
  NEXT_PUBLIC_API_BASE: z.string().url()
})

function parseEnv<T extends z.ZodTypeAny>(schema: T, source: Record<string, unknown>) {
  const r = schema.safeParse(source)
  if (!r.success) {
    console.error(r.error.format())
    throw new Error("Invalid environment variables")
  }
  return r.data as z.infer<T>
}

export const serverEnv = parseEnv(serverSchema, process.env)
export const clientEnv = parseEnv(clientSchema, process.env)

All lessons in this course

  1. App Router types; server vs client components
  2. Data fetching & action typing
  3. Env typing and config
← Back to TypeScript Academy