Skip to content
fusion-env

Usage

Create the env once, at boot

Call createAppEnv a single time and export the result. Because validation runs when you call it, importing this module is what triggers the check — so a misconfigured environment fails at startup, not mid-request:

src/lib/env.ts
import { createAppEnv, type AppEnv } from "@tikab-interactive/fusion-env";
 
export const env = createAppEnv(process.env);
export type { AppEnv };

Everywhere else, import env and read typed values — never reach for process.env again:

src/server/db.ts
import { env } from "#/lib/env";
 
// env.DATABASE_URL is `string | undefined`, already validated as a URL.
const url = env.DATABASE_URL ?? "postgres://localhost:5432/app";

Values are typed, not stringly-typed

Each field's type is inferred from its Zod rule, so optional vars are string | undefined and the compiler makes you handle the undefined:

.;
.;

Fail fast on bad config

A value that's present but invalid throws immediately — validation happens at the createAppEnv call, so the process never starts in a half-broken state:

// throws: SERVER_URL is present but not a valid URL
createAppEnv({ SERVER_URL: "not-a-url" });
 
// fine: absent optional vars are simply `undefined`
createAppEnv({}).SERVER_URL; // => undefined
 
// fine: an empty string is treated as "not set"
createAppEnv({ SERVER_URL: "" }).SERVER_URL; // => undefined

Server vs client at runtime

The VITE_ prefix is the boundary: in a Vite app, VITE_-prefixed vars are the only ones safe to read from browser code, while server vars stay on the server. fusion-env doesn't read the environment for you — you pass it in (process.env on the server) — so it works the same under Node, Bun, or a Vite server runtime. See the @t3-oss/env-core docs for framework-specific wiring of the client half.