DEV Community

Ahmed Rakan
Ahmed Rakan

Posted on

Handling Environment Variables Intelligently in Vite and React Applications

Handling Environment Variables in Applications

Environment variables are critical for setting configuration parameters that adapt as environments switch between development, testing, and production. Managing these variables in a robust, scalable way ensures smooth development, deployment, and maintenance. It benefits both developers working on the code and DevOps engineers building CI/CD pipelines.

Here, I propose an approach to minimize code duplication and maintenance effort while adhering to the principles of Don't Repeat Yourself (DRY) and Keep It Simple, Stupid (KISS). Additionally, I’ll outline alternative strategies with their pros and cons.


Proposed Approach: Prefix-Based Variable Management

  1. Define Environment Variables with Suffixes (_DEV, _PROD):
   VITE_API_URL_DEV=http://localhost:3000/v1
   VITE_BRAND_NAME_DEV=TablesXi
   VITE_API_URL_PROD=https://api.prod.com/v1
   VITE_BRAND_NAME_PROD=TablesXi
   VITE_MODE=dev
Enter fullscreen mode Exit fullscreen mode
  1. Define Keys Object:
   export const ENV_VARS = {
     VITE_API_URL: "VITE_API_URL",
     VITE_BRAND_NAME: "VITE_BRAND_NAME",
   };
Enter fullscreen mode Exit fullscreen mode
  1. Create a Utility Function:
   const environmentMode = import.meta.env.VITE_MODE;

   export const getEnvVar = (key) => {
     const mode = environmentMode === "dev" ? "_DEV" : "_PROD";
     return import.meta.env[`${key}${mode}`];
   };
Enter fullscreen mode Exit fullscreen mode
  1. Usage Example:
   const apiUrl = getEnvVar(ENV_VARS.VITE_API_URL);
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Centralized management of environment logic.
  • Minimal code duplication.
  • Easy to extend for new variables.

Disadvantages:

  • Slightly more verbose when adding new environment variables.

Alternative Approaches

1. Environment-Specific Configuration Files

  • Create separate files for each environment (e.g., config.dev.js, config.prod.js, or from the .env files, prod.env, dev.env).
  • Dynamically import based on the environment.
   const config = environmentMode === "dev" ? require("./config.dev") : require("./config.prod");
   export default config;
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Clear separation of environment-specific logic.
  • Easier to manage complex configurations.

Cons:

  • Requires additional maintenance for each environment.
  • Difficult to track changes across multiple files.

2. Centralized Switch/Conditional Logic

  • Use a single configuration file with if or switch statements.
   const config = {
     apiUrl: environmentMode === "dev" ? "http://localhost:3000/v1" : "https://api.prod.com/v1",
   };
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Single source of truth.
  • No need for prefixes or suffixes.

Cons:

  • Violates DRY when handling many variables.
  • Difficult to scale.

Key Considerations

  • Scalability: The solution should accommodate growing application needs with minimal rework.
  • Maintainability: Avoid repetitive patterns and scattered logic.
  • Developer Experience: Ensure ease of use for developers and DevOps engineers.

By adopting the prefix-based approach or carefully considering alternatives, you can achieve a clean, maintainable environment variable management strategy.

If you have suggestions or other approaches, feel free to share in the comments!

Best regards,

Ahmed

Top comments (0)