Browser
Seed a ManualEnvSource from the config your bundler injects, with no filesystem in the browser.
In the browser there is no filesystem and no process.env. Your bundler inlines configuration at build time, and you seed a ManualEnvSource from it, then read with the same typed API as everywhere else.
Import the browser build from envapt/browser. It is node-free and omits the file-only config APIs from its type.
Import from envapt/browser, not bare envapt. The envapt/browser entry omits the file-only config APIs (envPaths, baseDir, configureProfiles, and the rest) from its type, so a stray call is a compile error. Bare envapt leaves you on the Node types, where those APIs look available and instead throw EnvaptError.FileApiUnsupported at runtime. See Errors.
import { } from 'envapt/browser';
.('FEATURE_BETA', false); // readers work
.baseDir = '/tmp'; // a file-only API is not on the typeSeed from your bundler
Bundlers replace build-time env references with string literals: Vite exposes them on import.meta.env, webpack through DefinePlugin. Pass that object to ManualEnvSource, then read the values typed.
import { Envapter, ManualEnvSource, Converters } from 'envapt/browser';
Envapter.useSource(new ManualEnvSource(import.meta.env));
const apiUrl = Envapter.getUsing('VITE_API_URL', Converters.Url); // URL, not a raw string
const beta = Envapter.getBoolean('VITE_ENABLE_BETA', false); // booleanimport.meta.env.VITE_API_URL is a string; Envapter.getUsing('VITE_API_URL', Converters.Url) returns a URL, and getBoolean returns a boolean. ManualEnvSource snapshots the object and JSON-stringifies non-string values, so you can read Vite's boolean DEV and PROD flags too.
Anything you seed into a browser ManualEnvSource ships in your client bundle. Pass public configuration only,
never a secret or a server-side key.
Environment detection
Envapter.environment and the isProduction / isDevelopment / isTest helpers also read MODE, which Vite sets to development, production, or your --mode value. Because you bind import.meta.env, they work with no extra wiring. See Environment.
No filesystem
ManualEnvSource snapshots its object at construction, so mutating that object afterward does not change what envapt reads. There is no .env cascade and no file-only config APIs in the browser; calling one throws, as does reading before you bind a source. See Sources and Errors.
Decorators need a build step
@Envapt and the sugar decorators need a compile step (experimentalDecorators), the same as on Node and Workers; the functional API does not.
For the providers and the contract see Sources.