Vite
Learn how to use ArkEnv in a Vite project.
@arkenv/vite-plugin validates during Vite dev and production builds.
Transform mode inlines public VITE_ keys into the client bundle and
keeps server secrets out.
When does validation run?
When @arkenv/vite-plugin is registered, it discovers and validates env.ts
during Vite config resolution. An invalid or missing value aborts the dev
server or production build before Vite reports that it is ready. Relevant
.env and schema changes are validated again during HMR.
Without the plugin, validation is import-driven: env.ts runs when an
application module imports it. This distinction applies to both server and
client graphs; the plugin is what lets Vite validate the schema before the
graph is ready and transform client imports safely. See the
@arkenv/vite-plugin reference for the
plugin contract.
This documents the existing fail-fast behavior. ArkEnv does not add a default-off lazy-validation flag; a separate lazy mode would be an intentionally scoped feature.
For high-level architectural trade-offs, see Frameworks.
Quickstart
Scaffold Vite integration in an existing project using the CLI:
npx arkenv initpnpm dlx arkenv inityarn dlx arkenv initbunx arkenv initThe CLI installs @arkenv/vite-plugin, configures vite.config.ts, and scaffolds
your initial env.ts schema file.
Manual installation
If you prefer manual setup, install @arkenv/vite-plugin alongside your chosen
validation engine.
ArkType engine
Install @arkenv/core, arktype, and the Vite plugin:
npm install @arkenv/core arktype
npm install -D @arkenv/vite-pluginpnpm add @arkenv/core arktype
pnpm add -D @arkenv/vite-pluginyarn add @arkenv/core arktype
yarn add --dev @arkenv/vite-pluginbun install @arkenv/core arktype
bun install --dev @arkenv/vite-pluginStandard Schema engine
If you aren't using ArkType, install @arkenv/standard:
npm install @arkenv/standard
npm install -D @arkenv/vite-pluginpnpm add @arkenv/standard
pnpm add -D @arkenv/vite-pluginyarn add @arkenv/standard
yarn add --dev @arkenv/vite-pluginbun install @arkenv/standard
bun install --dev @arkenv/vite-pluginConfiguration
Add the plugin to your vite.config.ts.
Register the plugin
Import and register the plugin in your Vite plugins array:
import { } from "vite";
import from "@arkenv/vite-plugin";
export default ({
: [()],
});If you aren't using ArkType, import the plugin from @arkenv/vite-plugin/standard.
Define your schema
Create an env.ts file in your source tree. Import from @arkenv/core (or @arkenv/standard); the arkenv package is CLI-only:
import from "@arkenv/core";
export const = ({
: "string",
: "string",
: "'development' | 'production' | 'test' = 'development'",
});Import { env } from "./env" across your application. In server contexts (such as
SSR or development scripts), the real validation module runs at boot. In client
bundles, the Vite plugin rewrites the import to inline public VITE_ values and
guards private server keys.
Reuse the schema in Vite config
Vite does not load .env* files while evaluating vite.config.ts. When the config
needs typed values (for example server.port), compile a reusable schema with
type() and validate it with core arkenv() and loadEnv. Register the plugin
with no schema argument — it still rewrites env.ts in the client graph.
import { , } from "vite";
import from "@arkenv/vite-plugin";
import , { } from "@arkenv/core";
export const = ({
: "number.port = 5173",
: "string",
: "string",
});
export default (({ }) => {
const = (, { : (, .(), "") });
return {
// Plugin is transform-only — no schema argument
: [()],
: { : . },
};
});Learn more in Reusing schemas.
Client access
Import the validated env object from your schema module.
Do not read import.meta.env directly
Reading import.meta.env skips ArkEnv. Import { env } so public keys stay
typed and coerced and server secrets stay out of the client bundle.
Types and options: @arkenv/vite-plugin.
SSR and dual-graph execution
Vite maintains two distinct module graphs when building and serving full-stack or SSR applications:
- Server graph: During SSR execution and dev server requests,
env.tsexecutes real@arkenv/coreruntime validation at boot. It ensures private secrets (such asDATABASE_URL) and public configuration validate before handling requests. - Client graph: During client compilation,
@arkenv/vite-pluginintercepts and transformsenv.ts. It inlines publicVITE_*values as static literals and replaces private server keys with throwing runtime stubs. Client bundles omit the validator engine.
On Vite 6+, the Environment API drives this split: server consumers and custom
ssr environments keep the real module, everything else gets the client rewrite.
On Vite 4 and 5, the plugin falls back to the legacy SSR transform flag.