environment-variables
Setup
If src/lib/env.ts does not exist, install dependencies and create the files before proceeding:
bun add @t3-oss/env-core zod
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
emptyStringAsUndefined: true,
runtimeEnv: process.env,
server: {},
});
// src/lib/env.test.ts
import { describe, expect, test } from "vitest";
import { env } from "./env";
describe("env", () => {
test("initializes without error", () => {
expect(env).toBeDefined();
});
});
Variable Types
| Type | Prefix | Exposed to client | Example |
|---|---|---|---|
| Client | VITE_ |
Yes | VITE_API_URL |
| Server | None | No | DATABASE_URL |
| Shared | None | Both (build-time) | NODE_ENV, DEV |
Client = public endpoints, publishable keys, UI feature flags. Server = secrets, DB strings, internal URLs.
Environment Files
| File | Purpose | Git |
|---|---|---|
.env |
Development defaults (local URLs, non-sensitive) | Committed |
.env.local |
Secrets, API keys, overrides | Ignored |
Load order: .env.local overrides .env.
Adding a Variable
- Add Zod schema to
src/lib/env.tsinclient,server, orshared - Development default →
.env; secret →.env.local - Configure in deployment environment
- Add validation test to
src/lib/env.test.ts
Usage
import { env } from "@/lib/env";
Quick Reference
| Task | Action |
|---|---|
| Access var | import { env } from "@/lib/env" |
| Client var | client section, VITE_ prefix |
| Server var | server section, no prefix |
| Shared var | shared section, build-time values |
| Validation | Zod schemas: z.string(), z.boolean(), etc. |
Acceptance checklist
-
src/lib/env.tsexists with t3-env + Zod config -
src/lib/env.test.tsexists with validation tests - New variables added to correct section (
client,server,shared) - Defaults in
.env, secrets in.env.local - Deployment environment configured
More from kvnwolf/devtools
commit
Wraps up work by syncing documentation, committing, pushing, and opening a pull request. Use when committing code, finishing a task, pushing changes, or creating a PR.
10base
Scaffolds a new TypeScript project from scratch. Use when starting a new project, bootstrapping a codebase, or setting up a project from zero.
10unit-testing
Writes unit tests following behavior-driven conventions with vitest. Use when creating tests, adding test coverage, or writing regression tests.
9convex
Provides instructions for working with Convex backend projects. Use when setting up Convex, creating queries/mutations/actions, consuming Convex data from React, defining tables, testing Convex functions, configuring environment variables, or prefetching data in route loaders.
7e2e-testing
Writes end-to-end tests with Playwright Test for full user flow verification. Use when adding, modifying, or removing user flows in an application. Do not use for isolated component behavior — use component-testing instead.
5tanstack-start
Provides instructions for working with TanStack Start projects. Use when setting up, configuring, developing, creating routes, or creating server functions in a TanStack Start application.
5