Environment variables can be defined in .env and .env.[mode] files.

# .env.development
DATABASE_URL=postgresql://localhost:5432
 
# .env.production
DATABASE_URL=postgresql://database.example.com:5432
DATABASE_PASSWORD=some-secret-password
 
# .env
EMAIL_USER=John Doe
PUBLIC_ENV__SOME_KEY=123

The .env.production/.env.development file is loaded only in production/development while .env is always loaded, see Vite > .env Files.

For files not processed by Vite, you need to manually install dotenv for your .env values to also be available in files that aren't processed by Vite.

function somewhere() {
  // Environment variables prefixed with PUBLIC_ENV__ can be used anywhere: in server-side code
  // as well as in client-side code.
  import.meta.env.PUBLIC_ENV__SOME_KEY
}
function data() {
  // Environment variables without the PUBLIC_ENV__ prefix can be used only in server-side code.
  // If this data() hook is loaded only on the server-side (which is the case
  // by default) then DATABASE_PASSWORD can be accessed here.
  import.meta.env.DATABASE_PASSWORD
}

Keep in mind that import.meta.env.SOME_ENV is statically replaced:

// ❌ Won't work
import.meta.env['SOME_ENV']
// ❌ Won't work
const { SOME_ENV } = import.meta.env
// ✅ Works
import.meta.env.SOME_ENV
⚠️

As explained in Vite's security note:

Public whitelist

The following environment variables can be accessed from the client-side without having to prefix them with PUBLIC_ENV__:

  • STORYBOOK
💚

Config files

Note that import.meta.env isn't available in config files (neither vite.config.js nor +config.js).

A workaround is to use process.env instead of import.meta.env. But note that you'll then only be able to access environment variables coming from your operating system (you won't be able to access those defined in .env files).

See also