Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NodeJS 18 native feature caveats and dotenvx #774

Open
marcodali opened this issue Sep 4, 2023 · 7 comments
Open

NodeJS 18 native feature caveats and dotenvx #774

marcodali opened this issue Sep 4, 2023 · 7 comments

Comments

@marcodali
Copy link

Is it true that the new version of nodes 18 or 20 I don't remember exactly provides natively this feature of reading the values from a .env file without any dependency?

@dzienisz
Copy link

dzienisz commented Sep 5, 2023

https://nodejs.org/en/blog/release/v20.6.0

@motdotla
Copy link
Owner

motdotla commented Nov 2, 2023

TLDR: This is great to see from Node, but we don't recommend dropping dotenv just yet. The Node native feature is missing some key features at the moment.


Node.js 20.6.0 includes built-in support for .env files

Node v20.6.0+ adds native support for loading .env files.

node --env-file=.env index.js

Wow, cool!

Is dotenv dead? Stop using it? Not so fast. Don't drop dotenv just yet. There are some caveats you should know first.

First, let me say, it is great to see the NodeJS team adopt first-class .env support for developers. As one of the pioneers of dotenv, it's an honor. dotenv is depended on by more than 14 Million open source repos on GitHub alone and downloaded more than 35 Million times per week. dotenv has proven itself as a trusty friend to millions of developers worldwide.

Anyways, let's see how this built-in support works (or skip to the caveats section).

How it works

Install Node v20.6.0 or greater using nvm.

nvm install 20.6.0
nvm use 20.6.0
node -v
v20.6.0

Create your .env file.

HELLO="World"

Create your node script to make use of it.

// index.js
console.log(`Hello ${process.env.HELLO}`)

Run it with the --env-file flag.

node --env-file=.env index.js
Hello World

That's it!

Want to run it in production? Just point it to a .env.production file.

# .env.production
HELLO="production"
node --env-file=.env.production index.js

Caveats

The biggest current caveat is that this is still an experimental feature. That means it will ship with bugs and with missing feature support. The top hn comment sums it up well - albeit a bit grumpily.

image

I also want to stress the word current because this is all still under active development. These things take time. By the time you read this, some of these caveats might no longer be around.

Missing multiline support

The current implementation does not support multiline environment variables. If you attempt to include a multiline environment variable it will be undefined. For example:

# .env.multiline
HELLO="This
is
a
multiline"
// index.js
console.log(`Hello ${process.env.HELLO}`)
node --env-file=.env.multiline index.js
Hello undefined

Note: multiline support is being actively discussed and will probably get added in the near future.

Missing override option

You cannot override your system's environment variables with your .env file. There is no option.

# .env
HELLO="World"
// index.js
console.log(`Hello ${process.env.HELLO}`)
export HELLO="System"
node --env-file=.env index.js
Hello System

It prints Hello System rather then Hello World. There is no option to overwrite system variables.

If you need to do this then continue using dotenv with its override option.

Missing variable expansion

Variable expansion support for dotenv exists in a separate library dotenv-expand. But it is so widely used with 13 million downloads weekly that it is defacto considered part of dotenv.

As of this writing, Node does not support variable expansion. Instead, it will output the variable as a string.

# .env
PASSWORD="password123"
SECRET=$PASSWORD
// index.js
console.log(`The secret is ${process.env.SECRET}`)
node --env-file=.env index.js
The secret is $PASSWORD

So if you need variable expansion, you should continue using dotenv and dotenv-expand.

Missing .env.vault support

.env.vault files are the spiritual successors to .env files. They have multiple security advantages over .env files which you can read about here.

They are quite new, but also quite useful for production and ci, and are gaining adoption across multiple communities like node, python, rust, and more.

But as a new technology, they are unlikely to be adopted natively by Node until they earn similar widespread use to .env files. So keep using dotenv if you plan to make use of them.

#/-------------------.env.vault---------------------/
#/         cloud-agnostic vaulting standard         /
#/   [how it works](https://dotenv.org/env-vault)   /
#/--------------------------------------------------/
# development
DOTENV_VAULT_DEVELOPMENT="AtEC33ZfFJQMSE6C+EBX8nzTyQzfC+xhsIfGjyWr47jiHsUi07PHzX2/RmCB0PIi"
# production
DOTENV_VAULT_PRODUCTION="t9van8HefnTIHVlK3vQ6WYLtWEOvPunEnOphV3Hw3aBTBDuwLq22yU0Tdl5fAnk="

Conclusion

In conclusion, built-in support for .env files (even if currently experimental) is a huge and welcome step forward for Node. Big thanks to Yagiz Nizipli for making this happen. Go sponsor him on GitHub. He is doing incredible work for Node.

But there are some current caveats, and I would recommend against npm uninstall-ing dotenv for your production apps at this time. Wait until it is non-experimental and has added support for the missing features above.

@dzienisz
Copy link

dzienisz commented Nov 10, 2023

@motdotla great comment! I wonder why Node team half bake features? Like with Fetch? Is it so hard to make them fully baked?

@motdotla
Copy link
Owner

it is nice to see them add it though and further development is underway. you can support development by sponsoring @anonrig https://github.com/sponsors/anonrig

also, we are moving a lot of such effort into dotenvx going forward. it works everywhere - so you get consistent use of dotenv across every framework and language. https://github.com/dotenvx/dotenvx

@JonasDoe
Copy link

I'ld lke to add: missing env files will now cause the native env loader to throw an error, and that's intented. So seems like one should stick to to .dotenv.

@motdotla motdotla changed the title NodeJS 18 native feature to read from .env file NodeJS 18 native feature caveats Feb 6, 2024
@motdotla motdotla changed the title NodeJS 18 native feature caveats NodeJS 18 native feature caveats and `dotenvx Feb 6, 2024
@motdotla motdotla changed the title NodeJS 18 native feature caveats and `dotenvx NodeJS 18 native feature caveats and dotenvx Feb 6, 2024
@karlhorky
Copy link

karlhorky commented Mar 28, 2024

Seems like Node.js v20.12.0 just added process.loadEnvFile(path) and util.parseEnv(content) (via PR nodejs/node#51476) as well, in case you're looking for a Node.js built-in alternative to the dotenv runtime programmatic dotenv.config() API.

Not 100% sure, but I think the caveats / missing features that @motdotla mentioned (multiline support, overrides, variable expansion) still apply:

@motdotla
Copy link
Owner

Not 100% sure, but I think the caveats / missing features that @motdotla mentioned (multiline support, overrides, variable expansion) still apply:

yes, still same caveats, but I think they will be working toward that over the next few months from the chatter I've seen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants