vite-plugin-envsubst

raw JSON →
0.3.0 verified Mon Apr 27 auth: no javascript

A Vite plugin that transforms import.meta.env references to globalThis.env placeholders for runtime substitution via envsubst or Caddy's templating engine. Current stable version 0.3.0. Released in April 2025. Solves the problem of environment-specific builds by deferring variable injection to runtime, suitable for Docker/Kubernetes deployments. Key differentiators: only transforms declared variables from vite-env.d.ts, respects Vite's envPrefix, supports both envsubst and Caddy template syntax, and uses sourcemap-preserving transforms with a single runtime dependency (rolldown-string). Unlike other env injection plugins, it enables true build-once-deploy-anywhere without build-time environment knowledge.

error SyntaxError: Cannot use import statement outside a module
cause Using require() or ts-node without ESM enabled for this package
fix
Add "type": "module" to package.json or use .mts extension for vite.config.ts
error Error: Plugin envSubstPlugin is missing required option 'vite-env.d.ts' or no variables found
cause ImportMetaEnv interface not declared or empty in vite-env.d.ts
fix
Add interface ImportMetaEnv with readonly string fields in src/vite-env.d.ts
error TypeError: envSubstPlugin is not a function
cause Wrong import style (default import instead of named import)
fix
Use import { envSubstPlugin } from 'vite-plugin-envsubst'
gotcha Must declare environment variables in 'vite-env.d.ts' or they will NOT be transformed
fix Add interface ImportMetaEnv with readonly string fields for each variable in src/vite-env.d.ts
gotcha Only variables matching Vite's envPrefix (default VITE_) are transformed by default
fix Set envPrefix in Vite config to include non-VITE_ variables or declare them in vite-env.d.ts (still only VITE_ transformed unless prefix changed)
gotcha envsubst is not included in hardened nginx images like Chainguard's
fix Use Caddy template engine or install envsubst in Docker image explicitly
breaking Plugin only runs during build; dev server uses native import.meta.env (placeholders are not replaced)
fix For dev server, provide actual env vars via .env files or command line. The plugin skips transform in dev mode.
gotcha Importing from 'vite-plugin-envsubst' directly without ESM support can fail; no CommonJS require()
fix Use import syntax and set module resolution to ESM or 'bundler' in tsconfig.json
npm install vite-plugin-envsubst
yarn add vite-plugin-envsubst
pnpm add vite-plugin-envsubst

Configures Vite to transform declared import.meta.env variables into globalThis.env placeholders for runtime substitution.

// vite.config.ts
import { defineConfig } from 'vite';
import { envSubstPlugin } from 'vite-plugin-envsubst';

export default defineConfig({
  plugins: [
    envSubstPlugin({
      globalObject: 'globalThis',
      templateEngine: 'envsubst',
      include: [/\.([cm]?[jt]sx?)$/],
      exclude: [/node_modules/],
    }),
  ],
});

// src/vite-env.d.ts must declare variables:
/// <reference types="vite/client" />
interface ImportMetaEnv {
  readonly VITE_API_URL: string;
}
interface ImportMeta {
  readonly env: ImportMetaEnv;
}

// src/main.ts
const apiUrl = import.meta.env.VITE_API_URL;
console.log(apiUrl);