Skip to content

Type Generation

vite-env writes a vite-env.d.ts file to your project root so your editor knows the exact shape of every environment variable — without any manual type augmentation.

When It Is Generated

The file is written during the buildStart Vite hook, which fires on every dev server start and every production build. You never need to remember to regenerate it during normal development.

What It Creates

Two ambient module declarations are written to vite-env.d.ts:

  • virtual:env/client — contains only the client-side keys (those under client in your schema, i.e. VITE_-prefixed variables)
  • virtual:env/server — contains all keys: every server variable plus every client variable

All fields are typed readonly and optional fields (those using .optional() or .default() in Zod) get the ? modifier.

Zod to TypeScript Type Mapping

Zod schemaTypeScript type
z.string()string
z.number()number
z.boolean()boolean
z.enum([...])Union literal, e.g. 'debug' | 'info'
z.optional(...)Unwrapped inner type + ? on the field
z.default(...)Unwrapped inner type + ? on the field
z.pipe(...)Output type of the pipe
Anything elsestring (fallback)

Example Output

Given a schema with both server and client variables, the generated file looks like:

ts
// Auto-generated by @vite-env/core
// Do not edit manually — re-generated on every dev server start and build

declare module 'virtual:env/client' {
  const env: {
    readonly VITE_API_URL: string
    readonly VITE_APP_NAME: string
    readonly VITE_DEBUG?: boolean
    readonly VITE_LOG_LEVEL?: 'debug' | 'info' | 'warn' | 'error'
  }
  export { env }
  export default env
}

declare module 'virtual:env/server' {
  const env: {
    readonly DATABASE_URL: string
    readonly JWT_SECRET: string
    readonly DB_POOL_SIZE?: number
    readonly REDIS_URL?: string
    readonly VITE_API_URL: string
    readonly VITE_APP_NAME: string
    readonly VITE_DEBUG?: boolean
    readonly VITE_LOG_LEVEL?: 'debug' | 'info' | 'warn' | 'error'
  }
  export { env }
  export default env
}

Setup Tips

Add to .gitignore

vite-env.d.ts is generated output, not source. Add it to your .gitignore:

vite-env.d.ts

Make sure TypeScript sees it

Your tsconfig.json must include the project root (or the file explicitly) so the declarations are picked up:

json
{
  "include": ["."]
}

Or add the file explicitly:

json
{
  "include": ["vite-env.d.ts", "src"]
}

Postinstall pattern

On CI or fresh clones the file will not exist until the first build. Add a postinstall script so it is generated immediately after npm install:

json
{
  "scripts": {
    "postinstall": "vite-env types"
  }
}

Manual trigger

You can regenerate the file at any time without starting a build:

sh
npx vite-env types

This is useful when the file gets out of date after pulling changes to env.ts.

Released under the MIT License.

⚠️ You're reading unreleased (next) docs. Latest stable: v0.5.0 →