Build · configuration boundaries
Environment values
Presolve makes browser environment data an explicit compiler input. It never discovers dotenv files, reads ambient process state, or treats a Vite global as configuration authority.
1. Declare an environment input
Create a dotenv-style file with one unique NAME=VALUE declaration per line. Quoting, interpolation, duplicate names, and implicit file discovery are intentionally excluded.
PRESOLVE_PUBLIC_APP_NAME=Acme PortalPRESOLVE_PUBLIC_API_ORIGIN=https://api.example.comDATABASE_URL=postgres://privateOnly names beginning with PRESOLVE_PUBLIC_ can enter browser artifacts. Other valid names are recorded as server-owned names, but their values are omitted.
2. Read a public value
import { environment } from "presolve";export const appName = environment.public("PRESOLVE_PUBLIC_APP_NAME");The argument must be one string literal, and TypeScript authority must resolve the callee to Presolve’s exported intrinsic. Aliased imports are valid; a same-shaped local function is not.
3. Generate and select the manifest
pnpm exec presolve environment --file .env.production > environment.manifest.jsonpnpm exec presolve check --environment-manifest environment.manifest.jsonpnpm exec presolve build --environment-manifest environment.manifest.jsonThe manifest is immutable schema-v1 compiler input. check and build join every authority-proven read to that exact file before publication.
Published browser artifact
A successful build emits environment.browser.json containing exactly the public names read by admitted source. Repeated reads collapse to one entry. The Vite adapter can expose the digest-verified artifact as virtual:presolve/v1/environment.browser.json, but it cannot add values or rewrite source calls.
{"browserValues": {"PRESOLVE_PUBLIC_APP_NAME": "Acme Portal"}}What fails closed
Do not rely on process.env, import.meta.env, automatic .env loading, or deployment-provider injection in browser source. Server runtime configuration remains capability-specific and separate.