Packages@g14o/env-core
Client vs server
How createEnv protects server variables on the client.
How client protection works
createEnv returns a Proxy around the validated environment object (on both server and client):
- Server: the proxy is transparent — all validated server and client keys are readable.
- Client: only
clientschemas are validated at import time (missing server vars inprocess.envdo not throw). - Client access: any property that is not a declared
clientkey throws with the exact name, e.g.DATABASE_URLor typos likeNOT_DECLARED. - Interop:
__esModuleand$$typeofare ignored so bundlers and React do not trigger false positives.
Override server detection
import { createEnv } from "@g14o/env-core";
export const env = createEnv({
// ...
isServer: typeof window === "undefined", // or `true` / `false`
});Security
Server values are never validated or exposed on the client. Importing a single env.ts that defines server schemas still ships those names to the client bundle. For sensitive names, split into env/server.ts and env/client.ts.
Options reference
| Option | Description |
|---|---|
server | Server-only variables (validated on server; throw on client access) |
client | Client-safe variables (validated on server and client) |
clientPrefix | Optional prefix required on all client keys (type + runtime) |
runtimeEnv | Record to read values from (e.g. process.env) |
runtimeEnvStrict | Explicit per-key mapping; mutually exclusive with runtimeEnv |
emptyStringAsUndefined | Treat "" as undefined before validation |
isServer | Override server detection (default: typeof window === "undefined") |
onValidationError | Hook when schema validation fails |
onInvalidAccess | Hook when a server key is accessed on the client |
skipValidation | Bypass validation and client-access proxy (default: false) |