Toggle between multiple .env files like .env.development with node.js

52,945

Solution 1

You can specify which .env file path to use via the path option with something like this:

require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` })

Solution 2

I'm using the custom-env npm package to handle multiple .env files. Just put this at the top of your code:

require('custom-env').env();

and it will load environment variables from the file .env.X, where X is the value of you NODE_ENV environment variable. For example: .env.test or .env.production.

Here is a nice tutorial on how to use the package.

Solution 3

I just wanted to add this for other people who are having issues. The above two answers are both slightly off. let me explain. The guy above had to use path as in

  • the first example it's missing a ./ the ./ indicates current directory to Node.js. Thats why in the first example if the env file was not in the root of the PC it would never find it. Using path is a nasty work around but the best way to do it is to simply add a ./ this says "hey computer look in my current directory for this file".
//this says hey computer look in my current directory for this file. 
 
require('dotenv').config({ path: `./.env.${process.env.NODE_ENV}` })


//I reccomend doing a console.log as well to make sure the names match*
console.log(`./.env.${process.env.NODE_ENV}`)

Solution 4

From answers from above: This is the final result that worked for me.

.env.dev file in src dir.

import path from 'path';

dotenv.config({ path: path.join(__dirname, `./.env.${process.env.NODE_ENV}`)});
Share:
52,945
Jonas
Author by

Jonas

Updated on February 08, 2022

Comments

  • Jonas
    Jonas about 2 years

    I want to use separate .env files for each mode (development, production, etc...). When working on my vue.js projects, I can use files like .env.development or .env.production to get different values for the same env key. (example: in .env.development: FOO=BAR and in .env.production: FOO=BAZ, in development mode process.env.FOO would be BAR, in production i'd be BAZ).

    I'm working on an Express server and want to use these same kinds of .env files to store the port, db uri, user, pwd...

    I know I can edit the scripts in package.json like this:

    "scripts": {
        "start": "NODE_ENV=development PORT=80 node ./bin/www",
        "start-prod": "NODE_ENV=production PORT=81 node ./bin/www"
    }
    

    but this gets messy when using multiple variables.

    I've tried using dotenv but it seems like you can only use the .env file. Not .env.development and .env.production.

    Can I use the dotenv package or do I need another one? Or could I do this without any package at all?

  • Jonas
    Jonas about 5 years
    For anyone else: i finally went with this: const path = require('path'); require('dotenv').config({ path: path.join(__dirname, ../.env.${process.env.NODE_ENV})});
  • goldenmaza
    goldenmaza over 3 years
    If I use this solution I seem to need to place this line of code in every javascript file that I want to use the env values... Is there no global way so I can just have one line and all files access the values?
  • Admin
    Admin over 3 years
    @goldenmaza You can preload them when running your node service in terminal like this. node -r dotenv/config app.js dotenv_config_path=/custom/path/to/your/env/vars. See also here npmjs.com/package/dotenv
  • FrozenKiwi
    FrozenKiwi about 3 years
    DV bc This misinterprets either OP question or the doc: the doc advice is against using multiple .env files in the same environment (eg, loading main.env and test.env in the same process), not blanket advice against having multiple files.
  • FrozenKiwi
    FrozenKiwi about 3 years
    Apologies for DV @rom5jp (I would remove it if I could). I re-read the docs, and it does sound like it doesn't recommend multiple files. However, I suspect this advice was not intended for this context, as it basically negates most of the utility of .env file in the first place (unless you never run multiple environments on your local machine).
  • LukeT
    LukeT about 3 years
    That statement in the docs is for liability purposes. If you are using dotenv for a production NodeJS server with a large team that has different roles/responsibilities, and store secrets/creds in the .env file - then yes, Dev should never have access to Prod vars (especially sensitive vars). However, you can also use this package to store non-sensitive vars that will change across envs (such as remote urls) on client-side applications (such as this). The context defines how the package should be used.
  • Martin Omander
    Martin Omander almost 3 years
    In my opinion, the quoted recommendation against multiple .env files is poorly written and it's not clear what they mean. I agree that your config should vary between environments. But that means you will need one env file per environment. I think @FrozenKiwi is right: the recommendation is probably against multiple env files for one particular environment.
  • Pranaya Tomar
    Pranaya Tomar over 2 years
    NODE_ENV should not be used to set the application environment. A separate environment variable like APP_ENV may be used for this. You may want NODE_ENV to be production in your non production environments as well. nodejs.dev/learn/…
  • john-goldsmith
    john-goldsmith over 2 years
    @goldenmaza You shouldn't need to place this in every JS file. You'll want to add this as early as possible to your application bootstrap/entry point . Once it's added, you can access environment variables via process.env.
  • Miquel Canal
    Miquel Canal over 2 years
    I too was confused by dotenv's official statement. But what FrozenKiwi writes makes sense to me. They oppose the idea of multiple .env on a single environment. Not that we shouldn't have multiple .env to track each environments.
  • guy mograbi
    guy mograbi over 2 years
    I will even add and say - testing will always require the same configuration across different environments (local/ci etc.). To guarantee consistent configuration for testing, you should commit that file as part of the code. If the configuration includes secrets, encrypt it and only pass the decrypt key around.
  • Mike
    Mike about 2 years
    @guymograbi I'm not sure if I understand your comment fully, but that may not be true if your test is writing to a database, or if you want to turn off logging (via environment variable). The test should require its own configuration and that test configuration may look different on your local machine vs the remote machine; and may be different from the local development environment and remote deployment environment.
  • Mike
    Mike about 2 years
    I think we've all been confused by the dotenv's wording. They say We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. Your config should vary between deploys, and you should not be sharing values between environments., which seems like it discourages overrides/combinations -- the "AND" is the operative word. I think he majority of us are more curious about different local environments (e.g., .env.development, .env.production, etc) to test code locally w/ different resources.
  • Mike
    Mike about 2 years
    I also want to highlight their expectations/advice in how the .env is intended to be used. They say It should only include environment-specific values such as database passwords or API keys, which might explain why they don't expect to use a combination of environment files. Per: github.com/motdotla/dotenv#should-i-commit-my-env-file
  • Jesse de gans
    Jesse de gans about 2 years
    Really use case specific.