⚠️ AlabJS is under active development and not yet production-ready. APIs may change before v1.0. Feel free to explore, contribute, or star the repo.
Skip to content

AlabJS enforces a hard boundary between server-side and client-side environment variables. Variables must be explicitly opted into the browser bundle — accidental exposure of secrets is impossible by design.

Quick reference

PrefixAvailable inExample
ALAB_PUBLIC_Browser + ServerALAB_PUBLIC_API_URL
VITE_Browser + ServerVITE_THEME (Vite compat)
(no prefix)Server onlyDATABASE_URL, ALAB_REVALIDATE_SECRET

Client-side variables

Prefix any variable with ALAB_PUBLIC_ to make it available in the browser:

sh
# .env
ALAB_PUBLIC_API_URL=https://api.example.com
ALAB_PUBLIC_APP_NAME=My App

Access them via import.meta.env:

ts
// Works in any component, client or server
const apiUrl = import.meta.env.ALAB_PUBLIC_API_URL;
const appName = import.meta.env.ALAB_PUBLIC_APP_NAME;

These values are inlined at build time by Vite. They become literal strings in the browser bundle — there is no runtime lookup.

Server-only variables

Variables without the ALAB_PUBLIC_ prefix never leave the server:

sh
# .env
DATABASE_URL=postgres://...
ALAB_REVALIDATE_SECRET=super-secret
ALAB_ANALYTICS_SECRET=also-secret
CLOUDFLARE_API_TOKEN=cf-token

Access them on the server via process.env:

ts
// server function, API route, or server-side code only
import { defineServerFn } from "alabjs/server";

export const getUser = defineServerFn(async ({ id }) => {
  const db = await connect(process.env["DATABASE_URL"]!);
  return db.users.findById(id);
});

If you try to use process.env.DATABASE_URL in a client component, Vite replaces it with undefined — the value is never bundled.

Why not just ALAB_?

AlabJS reserves the bare ALAB_ prefix for framework-level server config:

sh
ALAB_CDN=cloudflare              # server config
ALAB_REVALIDATE_SECRET=secret    # server secret
ALAB_ANALYTICS_SECRET=secret     # server secret

If ALAB_ were the client prefix, any of these secrets could be accidentally exposed by forgetting the _PUBLIC_ part. The ALAB_PUBLIC_ prefix makes the intent explicit and impossible to misuse.

.env files

AlabJS uses Vite's standard .env file loading:

FileLoaded when
.envAlways
.env.localAlways (git-ignored)
.env.developmentalab dev only
.env.productionalab build + alab start only
.env.development.localalab dev only, git-ignored
.env.production.localalab build + alab start only, git-ignored

.local files are never committed. Add them to .gitignore and use them for machine-specific overrides.

TypeScript types

Add an env.d.ts file at the root of your project to get autocomplete for your variables:

ts
// env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly ALAB_PUBLIC_API_URL: string;
  readonly ALAB_PUBLIC_APP_NAME: string;
  // add more ALAB_PUBLIC_ vars here
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

Runtime env vars (server only)

Server-only variables can also be set at runtime without rebuilding:

sh
DATABASE_URL=postgres://prod-server/db alab start

This is useful in Docker / Kubernetes where secrets are injected at container start time rather than build time.

Built-in AlabJS variables

These are read by AlabJS internally — set them in your server environment, not in .env files committed to git:

VariableUsed byDescription
ALAB_CDNCDN Cache HeadersCDN provider: cloudflare or fastly
ALAB_REVALIDATE_SECRETISR + CDN purgeBearer token for /_alabjs/revalidate
ALAB_ANALYTICS_SECRETAnalyticsBearer token for /_alabjs/analytics
CLOUDFLARE_ZONE_IDCDN Cache HeadersCloudflare zone ID
CLOUDFLARE_API_TOKENCDN Cache HeadersCloudflare API token (Cache Purge permission)
FASTLY_SERVICE_IDCDN Cache HeadersFastly service ID
FASTLY_API_TOKENCDN Cache HeadersFastly API token
PUBLIC_URLSitemap, MessengerFull public URL of your site (e.g. https://example.com)
PORTServerPort to listen on (default 3000)

Released under the MIT License.