20

I ve setup a basic turborepo project and I want to share .env variables across the all the apps and some of packages. If I set one .env file in the root of project and how can all apps and packages access them. Or for my requirement do I need to set multiple .env files in all apps and packages?

8 Answers 8

13

As of December'22, the recommended way of doing this as per the official turbo docs is as follows:

  1. cd root-directory-of-your-project.
  2. npm add -D dotenv-cli (or with pnpm: pnpm add -D dotenv-cli -w).
  3. Create a .env file in the root directory of your project.
    • Add your .env to your project's root .gitignore.
  4. Add your variables to the newly created .env file.
    • If you are using nextjs remember to prefix your public variables with NEXT_PUBLIC_* (example: NEXT_PUBLIC_GOOGLE_ANALYTICS_TOKEN=1234).
  5. On your turbo.json file, add the variables on which each pipeline job depends.
    • Example:
    {
      "$schema": "https://turborepo.org/schema.json",
      "pipeline": {
        "dev:frontend": {
          "outputs": ["dist/**", ".next/**"],
          "env": ["NEXT_PUBLIC_GOOGLE_ANALYTICS_TOKEN"]
        },
        "dev:backend": {
          "outputs": ["dist/**", ".next/**"],
          "env": ["DATABASE_URL"]
        }
      }
    }
    
  6. Restart your local development server. Try logging process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_TOKEN.

Once finished, the structure of the project should look similar to the following:

apps
    backend     <<< Your backend code. You don't need to keep any .env file here.
    frontend    <<< Your frontend code. You don't need to keep any .env file here.
package.json    <<< Where you should install dotenv-cli as a dev dependency.
turbo.json      <<< Where pipeline jobs and their dependencies on environment variables are specified.
.env            <<< Where all your environment variables will be stored.
4

Following turbo docs - Using environment variables

Steps:

  1. Add dotenv-cli to the project root.
# Installs dotenv-cli in the root workspace
yarn add dotenv-cli --ignore-workspace-root-check
  1. Update the root script (what runs your project with turbo), in my case "dev"
"scripts": {
    "dev": "dotenv -- turbo run dev",
    ...
}   

you may leave the turbo default globalDependencies setup in turbo.json

"globalDependencies": ["**/.env.*local"]

Optional:

  1. If you have a CRA, create a .env.local in the CRA app root and expand the variable

in workspace root .env:

VARIABLE=value

in CRA root .env.local:

REACT_APP_VARIABLE=${VARIABLE}

Restart server.

2

To load the env variables from .env into the process env you can use https://www.npmjs.com/package/dotenv.

Then to share the env variables in your monorepo :

In each workspace/app add require('dotenv').config({path: /custom/path/to/.env}) (assuming common js module resolution here) as early as possible as per docs (meaning e.g. for a next js app in next.config.js), where /custom/path/to/.env would be the relative path to your root .env (e.g. two folders up:../../.env)

1
  • This won't work for shared workspace libraries though... as the relative path will be changed compared to the library files.
    – Spock
    Commented Jun 20, 2023 at 20:59
1

You can specify the globalDependencies option in your turbo config or use the --global-deps CLI flag.

{ 
   // ... rest of the turbo config
   globalDependencies: ['.env']
}

or

turbo run build --global-deps=".env.*"

References from docs:

https://turborepo.org/docs/reference/configuration#globaldependencies https://turborepo.org/docs/reference/command-line-reference#--global-deps

1
  • 13
    but it's not loading any env variables...
    – Adam
    Commented Feb 4, 2022 at 7:53
1

The globalDependencies mentioned on the other answers is like the docs says:

A list of file globs for implicit global hash dependencies. The contents of these files will be included in the global hashing algorithm and affect the hashes of all tasks. This is useful for busting the cache based on .env files (not in Git) or any root level file that impacts workspace tasks

So, it's needed to cache that specific task, build etc... on turbo caching but not to load it on the application.

To load env variables from a centralized .env file into multiple processes, you may use my new package https://www.npmjs.com/package/dotenv-mono, which was designed specifically for this purpose.

  1. Install dotenv-mono (yarn add dotenv-mono or npm install dotenv-mono --save)

  2. Place your .env file in the root of your project

  3. Then load it as follows on your packages/applications init file (index.{js,ts}, next.config.js, etc...):

    require("dotenv-mono").load();
    

Check out the github page for more documentation https://github.com/marcocesarato/dotenv-mono

0
1

This package @dotenv-run/cli might help.

.env.* files can be defined in the root workspace and overriden by each application

/workspace
 apps
    frontend1
       .env.local # API_USERS=http://localhost:3001/users
       src/
.env.dev # API_BASE=https://dotenv-run.dev
.env.prod # API_BASE=https://dotenv-run.app
.env # API_USERS=$API_BASE/api/v1/users API_AUTH=https://$API_BASE/auth
package.json
turbo.json
$> cd /workspace/apps/frontend1
$> NODE_ENV=dev dotenv-run -- bash -c 'printf "✨API_USERS $API_USERS\n✨ API_AUTH $API_AUTH"'
✔ /workspace/apps/frontend1/.env.local
✔ /workspace/.env.dev
✔ /workspace/.env
✨ API_USERS http://localhost:3001/users
✨ API_AUTH https://dotenv-run.dev/api/v1/auth
1
  1. Add dotenv-cli, in your project root
npm add -D dotenv-cli
  1. update script
"dev": "dotenv -- turbo run dev",
  1. Add .env file to the project root

From Docs

0

I've found this approach to work.

  1. Install env-cmd (yarn install env-cmd)
  2. Make a shell script called turbo-run.sh that does the following:
# remember to use direct paths to files because yarn has a habit
# of stripping out `--` flags (which are used in turborepo to pass
# in extra args to turbo commands)
./node_modules/.bin/env-cmd \
  --file $ENV_FILE \
    ./node_modules/.bin/turbo run \
      $@

(also chmod +x it so that you can execute it)

  1. Then setup your package.json scripts to have a turbo-run command that calls ./turbo-run.sh
  2. Now you can do yarn turbo-run foo and ensure that it always calls env-cmd with the appropriate ENV_FILE file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.