Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.envless.cloud/llms.txt

Use this file to discover all available pages before exploring further.

The rule

Server secrets must never end up in a client bundle. envless enforces this with four independent layers — types, runtime, bundler, and lint — so any one of them failing still leaves the others standing.

Two imports

import { env } from '@goenvless/envless/server';  // all variables
import { env } from '@goenvless/envless/client';  // client-flagged only
  • /server exposes every variable. Use in API routes, server components, server actions, middleware, scripts, and background jobs.
  • /client exposes only variables you’ve marked client in the dashboard. Use in browser code, 'use client' files, and any module that ships to the browser.

Visibility flag

Every variable in the Envless dashboard has a visibility setting:
VisibilityAvailable in /serverAvailable in /clientBundling
server (default)❌ — type error and runtime throwNever enters client chunks
clientInlined as a string literal at build time
That single flag drives everything: type generation, runtime proxy, bundler behavior.

How values reach the browser

Client variables can’t be fetched at runtime in the browser — that would require shipping the decryption key. Instead they’re inlined at build time:
// what you wrote
import { env } from '@goenvless/envless/client';
fetch(env.NEXT_PUBLIC_API_URL);

// what the bundler emits for client chunks
fetch("https://api.acme.com");
This is the same trick used by Next’s NEXT_PUBLIC_* and Vite’s VITE_*envless just owns the flagging in one place instead of relying on prefix discipline.

What ships where

Server chunkClient chunk
Loader code✅ runs at boot❌ stripped
Decryption key✅ from cache or ENVLESS_TOKEN❌ never
Server-flagged values✅ live, fetched at boot❌ not present
Client-flagged values✅ live✅ inlined as literals

The four layers of enforcement

1

Type errors

envless types generates two separate module declarations. env.STRIPE_SECRET from /client doesn’t autocomplete and fails tsc.
2

Runtime throw

The /client proxy throws on access to any non-client key, even if you bypass types.
3

Bundler strip

The build plugin only inlines client-flagged keys into client chunks. Server keys referenced in client code resolve to undefined.
4

ESLint rule

@goenvless/envless/eslint errors on import '@goenvless/envless/server' inside any file the framework treats as client ('use client', *.client.ts).

Next.js example

// app/api/checkout/route.ts  — server
import { env } from '@goenvless/envless/server';
const stripe = new Stripe(env.STRIPE_SECRET);
// app/checkout/page.tsx  — client component
'use client';
import { env } from '@goenvless/envless/client';
fetch(env.NEXT_PUBLIC_API_URL);
A 'use client' file importing /server fails at lint. Even with lint disabled, server variables are undefined at runtime — loud immediate failure, not silent leak.

Tradeoff to know

Client variables are frozen at build time (like every other framework). Rotating one requires a new build. Server variables are live — rotate them in the dashboard, restart the process, done.