← Back to archive

Repo of the Day

t3-oss/t3-env

Published: Feb 7, 2026

Open repository ↗

Deploying your app with invalid environment variables is a hassle. This package helps you to avoid that.

I'm using this package in my Tanstack Start application now and it works well. One thing that I did need to do is add:

runtimeEnv: { ...import.meta.env, ...process.env }

So that both the server and vite env variables would be available. This should be safe though because it still prevents any server: {} variables from being used on the client side from what I can tell.

Summary

t3-env is a TypeScript library that validates environment variables at runtime using schemas, preventing deployment failures caused by missing or malformed configuration. It supports framework-specific integrations such as Next.js and Nuxt, and works with any Standard Schema compliant validator including Zod and Valibot. The package exposes a typed env object so that validated values are available throughout the application with full autocompletion and type inference.

What it is useful for

The package is useful when an application depends on several environment variables and you want configuration errors caught at startup rather than at request time. Common use cases include:

  • Validating required values like DATABASE_URL and API keys, so the app fails fast instead of crashing on first use
  • Enforcing a boundary between server-only variables and browser-exposed ones; the README notes that accessing server variables on the client will throw, and that client variables in Next.js must be prefixed with NEXT_PUBLIC_
  • Applying schema rules such as z.string().min(1), transforms, and defaults to environment values
  • Replacing scattered process.env.X references with a single typed import, which improves refactoring and code review

It fits naturally in TypeScript projects where runtime safety and compile-time types are both priorities.

How engineers can use it

The README documents installation with npm, pnpm, bun, or deno using a framework-specific package such as @t3-oss/env-nuxt or @t3-oss/env-nextjs. Full reference material lives at https://env.t3.gg, which the README points to for additional framework support and Standard Schema details.

A typical setup defines a schema file:

// src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import * as z from "zod";

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

The exported env object is then imported where configuration is needed, with TypeScript inferring the correct types for each property.

Documented limitations to be aware of:

  • The package is ESM only
  • It requires a tsconfig with a module resolution that reads package.json#exports (NodeNext when transpiling with tsc, Bundler when using a bundler)
  • Next.js users must manually destructure every variable into runtimeEnv so the bundler includes them in Edge and Client output

The project is licensed under MIT, and contributors are directed to use Bun with a changeset before opening a pull request.