Introduction
Contract-first environment configuration with typed schemas. Define your env once with Standard Schema, merge per-environment config with your environment variables, and read typed values in your code.
@vlandoss/env lets you describe every variable your app expects in a single Standard Schema contract (Zod, Valibot, ArkType…), then resolves it against per-environment config files and your environment variables at boot. Missing or malformed values fail the process before user code ever reads them.
The core is runtime-agnostic — Node, Bun, Deno, browsers, Workers, Edge. File-based config loading lives in a separate, opt-in entrypoint so the core stays portable, and client-side adapters (Vite plugin, React <EnvScript />) ship as their own optional entrypoints too.
The shape of a typical setup
The contract — every variable your app expects, grouped into branches.
import { schema, type Config } from "@vlandoss/env";
import * as z from "zod";
export const Env = schema({
server: {
HOST: z.string(),
PORT: z.coerce.number().int().positive()
},
db: {
URL: z.string()
},
});
export type EnvConfig = Config<typeof Env>;The wiring — combine the schema with per-environment config and surface a single typed env object.
import { defineEnv } from "@vlandoss/env";
import { loadConfig } from "@vlandoss/env/fs";
import { Env } from "./schema.ts";
export const env = defineEnv({
schema: Env,
config: loadConfig(Env)
});env.server.PORT is number. Reading anything not in the schema is a compile error.
Entrypoints
| Entrypoint | Runtime | Description |
|---|---|---|
@vlandoss/env | Any | The core — declare schemas and resolve a typed env at boot. |
@vlandoss/env/fs | Node / Bun / Deno | Discover and load per-environment config files from disk. |
@vlandoss/env/vite | Build time | Vite plugin that wires config and the current env name into your bundle. |
@vlandoss/env/react | SSR / SSG | React component that ships the server-resolved env to the browser. |
@vlandoss/env/zod | Any | Opinionated Zod primitives for common env-var shapes (port, host, bool, …). |
Where to go next
- Getting started — install and wire up a minimal Node app.
- Concepts — the mental model: resolution order, env-var naming,
envName()precedence. - Guides — recipes per runtime (Node, SPA, SSR) and per task (composition, custom modes).
- API reference — every export, organized by entrypoint.
- Community — contribute, file issues, and follow Variable Land.