> ## Documentation Index
> Fetch the complete documentation index at: https://next-safe-env.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Use next-safe-env in a Vite project

> Validate import.meta.env variables in Vite with next-safe-env. The vite adapter enforces VITE_ prefixes and keeps server vars out of the browser bundle.

`next-safe-env` works in Vite projects through its `vite` adapter, which enforces the `VITE_` prefix on all client schema keys and reads client variables from `import.meta.env` instead of `process.env`. You get the same typed, validated env object you would in a Next.js app - the adapter handles the differences in how Vite exposes variables to the browser bundle.

## Create your env file

<Steps>
  <Step title="Install next-safe-env">
    ```bash theme={null}
    npm install next-safe-env
    ```
  </Step>

  <Step title="Create src/env.ts">
    Define your server and client schemas. All client keys must be prefixed with `VITE_`. In `runtimeEnv`, use `import.meta.env` for client variables and `process.env` for server variables.

    ```typescript theme={null}
    // src/env.ts
    import { createEnv, str, url, port, bool } from 'next-safe-env'

    export const env = createEnv({
      server: {
        DATABASE_URL: url(),
        PORT:         port().default(3000),
      },
      client: {
        VITE_API_URL:   url(),
        VITE_APP_NAME:  str().default('My App'),
        VITE_DEBUG:     bool().default(false),
      },
      runtimeEnv: {
        DATABASE_URL:  process.env.DATABASE_URL,
        PORT:          process.env.PORT,
        VITE_API_URL:  import.meta.env.VITE_API_URL,
        VITE_APP_NAME: import.meta.env.VITE_APP_NAME,
        VITE_DEBUG:    import.meta.env.VITE_DEBUG,
      },
      adapter: 'vite',
    })
    ```
  </Step>

  <Step title="Import env anywhere in your app">
    ```typescript theme={null}
    import { env } from './env'

    env.DATABASE_URL   // string  (server-only)
    env.PORT           // number  (server-only)
    env.VITE_API_URL   // string
    env.VITE_APP_NAME  // string
    env.VITE_DEBUG     // boolean
    ```
  </Step>
</Steps>

## `VITE_` prefix enforcement

The `vite` adapter checks every key in your `client` schema before validation runs. If any key does not start with `VITE_`, the adapter throws immediately:

```
Error: [next-safe-env] Client env var "API_URL" must be prefixed with VITE_.
```

Vite only exposes variables with the `VITE_` prefix to the browser bundle. Any client variable without the prefix would be silently `undefined` at runtime - `next-safe-env` turns that silent failure into a loud startup error.

## Auto-detection

If you omit `adapter: 'vite'` but any of your client schema keys start with `VITE_`, `next-safe-env` detects this and selects the `vite` adapter automatically. You will see a console warning prompting you to set the adapter explicitly:

```
[next-safe-env] Detected VITE_ client keys - using vite adapter. Set adapter: 'vite' explicitly to suppress this warning.
```

Add `adapter: 'vite'` to your config to suppress the warning and make the intent clear.

<Note>
  Use `import.meta.env.VITE_*` in `runtimeEnv` for client variables and `process.env.*` for server variables. Vite statically replaces `import.meta.env.VITE_*` references at build time, which is how it keeps those values out of the server bundle and vice versa.
</Note>
