ArkEnv

Typing import.meta.env

For most use cases, you'll want to access your environment variables in your client code. In a Vite project, this is done via import.meta.env.

With ArkEnv, this can be typesafe with the one-time setup below. After this, each time you add/remove environment variables from your schema, your import.meta.env will always be typesafe - no codegen needed.

Setup

Important

You must have the core arkenv package installed as a dependency in your project. See ArkEnv quickstart for instructions.

Add this to a vite-env.d.ts file in your src directory:

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

type ImportMetaEnvAugmented =
	import("@arkenv/vite-plugin").ImportMetaEnvAugmented<
		typeof import("../vite.config").Env
	>;

interface ViteTypeOptions {
	// By adding this line, you can make the type of ImportMetaEnv strict
	// to disallow unknown keys.
	// See: https://vite.dev/guide/env-and-mode#intellisense-for-typescript
	// ⚠️ This option requires Vite 6.3.x or higher
	strictImportMetaEnv: unknown;
}

// Augment import.meta.env with your schema
// Only `VITE_*` prefixed variables will be included
interface ImportMetaEnv extends ImportMetaEnvAugmented {}

Usage

Once set up, import.meta.env is fully typesafe:

src/app.tsx
// TypeScript knows about your VITE_* variables
const apiUrl = import.meta.env.VITE_API_URL; // ✅ Typesafe
const port = import.meta.env.PORT; // ❌ Error: PORT is not in ImportMetaEnv

// Autocomplete works too!
import.meta.env.VITE_ // Shows all your VITE_* variables

How it works

The ImportMetaEnvAugmented type:

  1. Extracts the inferred type from your schema (the result of type() from arkenv)
  2. Filters to only include variables matching the Vite prefix (defaults to "VITE_")
  3. Makes them available on import.meta.env with full type safety

Server-only variables (like PORT) are automatically excluded from the client bundle and won't appear in import.meta.env.

Read more in the Vite documentation.

As your project grows

You might want to define your schema in a dedicated file for better organization:

src/env.ts
import {  } from "arkenv/arktype";

export const  = ({
	: "number.port",
	: "string",
	: "string",
	: "number",
	: "boolean",
});

export type  = typeof .;
vite.config.ts
import arkenvVitePlugin from "@arkenv/vite-plugin";
import { defineConfig } from "vite";
import { Env } from "./src/env";

export default defineConfig({
	plugins: [arkenvVitePlugin(Env)],
});
src/vite-env.d.ts
/// <reference types="vite/client" />

type ImportMetaEnvAugmented =
	import("@arkenv/vite-plugin").ImportMetaEnvAugmented<
		typeof import("./env").Env
	>;

interface ViteTypeOptions {
	strictImportMetaEnv: unknown;
}

interface ImportMetaEnv extends ImportMetaEnvAugmented {}

Important

Imports will break type augmentation

If the ImportMetaEnv augmentation does not work, make sure you do not have any import statements in vite-env.d.ts. See the TypeScript documentation for more information.

Credit

This implementation is inspired by vite-plugin-validate-env by Julien-R44.