Node.JS and environment variables

I just went through this nice article and Iย just wanted to add a few things you do not usually find in articles about environment variables.

Everyone (maybe) knows that you can reach environment variables through the process.env object in Node.JS.

Let’s consider a small project (with a basic package.json file), with a server.js file with this content:

console.log(JSON.stringify(process.env, null, 2));

Here is the result when I run node server.js:

{
  "CLOUDSDK_PYTHON": "python2",
  "CLOUDSDK_PYTHON_ARGS": "-S",
  "CLOUDSDK_ROOT_DIR": "/opt/google-cloud-sdk",
  "COLORFGBG": "default;default",
  "COLORTERM": "rxvt",
  "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus",
  "DESKTOP_SESSION": "i3",
  "DESKTOP_STARTUP_ID": "i3/urxvt/3346-81-jtutu_TIME224520596",
  "DISPLAY": ":0",
  "EDITOR": "vim",
  "GDMSESSION": "i3",
  "GDM_LANG": "en_US.utf8",
  "GOOGLE_CLOUD_SDK_HOME": "/opt/google-cloud-sdk",
  "GOPATH": "/home/siegfried/go",
  "GTK_IM_MODULE": "ibus",
  "GTK_MODULES": "canberra-gtk-module",
  "HOME": "/home/siegfried",
  "LANG": "en_US.utf8",
  "LOGNAME": "siegfried",
  "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:",
  "MAIL": "/var/spool/mail/siegfried",
  "MOZ_PLUGIN_PATH": "/usr/lib/mozilla/plugins",
  "PATH": "/home/siegfried/.config/fnm/bin:/home/siegfried/.config/fnm/bin:/home/siegfried/.local/bin:/root/.gem/ruby/2.4.0/bin:/home/siegfried/.gem/ruby/2.4.0/bin:/home/siegfried/go/bin/:/home/siegfried/.fzf/bin:/opt/google-cloud-sdk/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
  "PWD": "/home/siegfried/dev/test/env",
  "QT_IM_MODULE": "ibus",
  "SHELL": "/usr/bin/fish",
  "SHLVL": "2",
  "TERM": "rxvt-unicode-256color",
  "USER": "siegfried",
  "VISUAL": "vim",
  "WINDOWID": "50331657",
  "XAUTHORITY": "/home/siegfried/.Xauthority",
  "XDG_CURRENT_DESKTOP": "i3",
  "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/siegfried",
  "XDG_RUNTIME_DIR": "/run/user/1000",
  "XDG_SEAT": "seat0",
  "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0",
  "XDG_SESSION_DESKTOP": "i3",
  "XDG_SESSION_ID": "c2",
  "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0",
  "XDG_SESSION_TYPE": "x11",
  "XDG_VTNR": "7",
  "XMODIFIERS": "@im=ibus"
}

And here is the result when I run the same program with npm start:

{
  "npm_config_save_dev": "",
  "npm_config_shrinkwrap": "true",
  "npm_config_init_license": "ISC",
  "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:",
  "npm_config_save": "true",
  "CLOUDSDK_PYTHON": "python2",
  "npm_config_link": "",
  "npm_config_timing": "",
  "npm_execpath": "/home/siegfried/.config/fnm/lib/node_modules/npm/bin/npm-cli.js",
  "npm_config_user": "1000",
  "LANG": "en_US.utf8",
  "GDM_LANG": "en_US.utf8",
  "npm_config_bin_links": "true",
  "GOOGLE_CLOUD_SDK_HOME": "/opt/google-cloud-sdk",
  "npm_config_proxy": "",
  "DISPLAY": ":0",
  "npm_config_only": "",
  "npm_config_description": "true",
  "EDITOR": "vim",
  "npm_config_ignore_prepublish": "",
  "npm_config_editor": "vim",
  "npm_config_tag": "latest",
  "npm_config_global": "",
  "COLORTERM": "rxvt",
  "npm_config_browser": "",
  "npm_config_if_present": "",
  "npm_config_local_address": "",
  "npm_config_versions": "",
  "MOZ_PLUGIN_PATH": "/usr/lib/mozilla/plugins",
  "npm_config_access": "",
  "npm_config_script_shell": "",
  "npm_package_scripts_start": "node server.js",
  "npm_config_optional": "true",
  "npm_config_user_agent": "npm/5.3.0 node/v8.2.1 linux x64",
  "npm_config_init_version": "1.0.0",
  "XDG_VTNR": "7",
  "npm_config_registry": "https://registry.npmjs.org/",
  "npm_config_proprietary_attribs": "true",
  "npm_config_init_module": "/home/siegfried/.npm-init.js",
  "npm_package_main": "index.js",
  "npm_config_sso_poll_frequency": "500",
  "npm_config_strict_ssl": "true",
  "npm_config_sso_type": "oauth",
  "npm_config_loglevel": "notice",
  "npm_config_save_exact": "",
  "npm_config_production": "",
  "XDG_SESSION_ID": "c2",
  "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/siegfried",
  "USER": "siegfried",
  "npm_package_license": "ISC",
  "DESKTOP_SESSION": "i3",
  "npm_config_allow_same_version": "",
  "npm_config_userconfig": "/home/siegfried/.npmrc",
  "npm_lifecycle_event": "start",
  "npm_config_depth": "Infinity",
  "npm_config_searchexclude": "",
  "GOPATH": "/home/siegfried/go",
  "npm_config_umask": "0022",
  "npm_config_onload_script": "",
  "npm_config_shell": "/usr/bin/fish",
  "npm_package_description": "",
  "npm_config_logs_max": "10",
  "npm_config_searchlimit": "20",
  "npm_package_author": "",
  "PWD": "/home/siegfried/dev/test/env",
  "npm_config_node_version": "8.2.1",
  "npm_config_searchopts": "",
  "npm_config_unicode": "true",
  "HOME": "/home/siegfried",
  "npm_config_group": "1000",
  "npm_config_cache_min": "10",
  "npm_config_cache": "/home/siegfried/.npm",
  "npm_config_save_optional": "",
  "npm_config_init_author_name": "",
  "npm_config_always_auth": "",
  "npm_config_argv": "{\"remain\":[],\"cooked\":[\"start\"],\"original\":[\"start\"]}",
  "XDG_SESSION_TYPE": "x11",
  "npm_config_progress": "true",
  "npm_config_scripts_prepend_node_path": "warn-only",
  "npm_config_ca": "",
  "npm_config_init_author_url": "",
  "npm_config_cache_max": "Infinity",
  "npm_package_scripts_test": "echo \"Error: no test specified\" && exit 1",
  "XDG_SESSION_DESKTOP": "i3",
  "npm_config_cache_lock_wait": "10000",
  "npm_config_send_metrics": "",
  "npm_config_cert": "",
  "npm_config_prefer_online": "",
  "npm_config_global_style": "",
  "CLOUDSDK_ROOT_DIR": "/opt/google-cloud-sdk",
  "npm_config_tag_version_prefix": "v",
  "npm_config_ignore_scripts": "",
  "npm_config_dry_run": "",
  "npm_config_usage": "",
  "DESKTOP_STARTUP_ID": "i3/urxvt/3346-81-jtutu_TIME224520596",
  "npm_config_parseable": "",
  "npm_config_metrics_registry": "https://registry.npmjs.org/",
  "GTK_MODULES": "canberra-gtk-module",
  "npm_config_globalconfig": "/home/siegfried/.config/fnm/etc/npmrc",
  "npm_config_cache_lock_retries": "10",
  "npm_config_cafile": "",
  "npm_config_fetch_retry_mintimeout": "10000",
  "MAIL": "/var/spool/mail/siegfried",
  "npm_config_ham_it_up": "",
  "npm_config_version": "",
  "npm_lifecycle_script": "node server.js",
  "VISUAL": "vim",
  "npm_config_git": "git",
  "npm_config_legacy_bundling": "",
  "npm_config_viewer": "man",
  "TERM": "rxvt-unicode-256color",
  "SHELL": "/usr/bin/fish",
  "npm_config_git_tag_version": "true",
  "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0",
  "npm_config_https_proxy": "",
  "QT_IM_MODULE": "ibus",
  "XMODIFIERS": "@im=ibus",
  "npm_config_save_prod": "",
  "npm_config_fetch_retry_maxtimeout": "60000",
  "XDG_CURRENT_DESKTOP": "i3",
  "npm_config_sign_git_tag": "",
  "npm_config_long": "",
  "npm_config_message": "%s",
  "npm_config_key": "",
  "npm_config_rebuild_bundle": "true",
  "XDG_SEAT": "seat0",
  "SHLVL": "3",
  "COLORFGBG": "default;default",
  "npm_config_fetch_retry_factor": "10",
  "npm_config_prefer_offline": "",
  "npm_node_execpath": "/home/siegfried/.config/fnm/bin/node",
  "npm_config_prefix": "/home/siegfried/.config/fnm",
  "npm_config_also": "",
  "npm_config_maxsockets": "50",
  "WINDOWID": "50331657",
  "npm_config_init_author_email": "",
  "npm_config_fetch_retries": "2",
  "npm_config_json": "",
  "GDMSESSION": "i3",
  "npm_package_version": "1.0.0",
  "LOGNAME": "siegfried",
  "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus",
  "XDG_RUNTIME_DIR": "/run/user/1000",
  "npm_config_save_bundle": "",
  "npm_config_tmp": "/tmp",
  "XAUTHORITY": "/home/siegfried/.Xauthority",
  "npm_config_rollback": "true",
  "npm_config_globalignorefile": "/home/siegfried/.config/fnm/etc/npmignore",
  "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0",
  "npm_config_offline": "",
  "PATH": "/home/siegfried/.config/fnm/lib/node_modules/npm/bin/node-gyp-bin:/home/siegfried/dev/test/env/node_modules/.bin:/home/siegfried/.config/fnm/bin:/home/siegfried/.config/fnm/bin:/home/siegfried/.local/bin:/root/.gem/ruby/2.4.0/bin:/home/siegfried/.gem/ruby/2.4.0/bin:/home/siegfried/go/bin/:/home/siegfried/.fzf/bin:/opt/google-cloud-sdk/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
  "npm_config_engine_strict": "",
  "npm_config_searchstaleness": "900",
  "npm_config_save_prefix": "^",
  "npm_config_color": "true",
  "npm_config_scope": "",
  "npm_config_unsafe_perm": "true",
  "NODE": "/home/siegfried/.config/fnm/bin/node",
  "CLOUDSDK_PYTHON_ARGS": "-S",
  "npm_config_heading": "npm",
  "npm_config_auth_type": "legacy",
  "npm_package_name": "env",
  "npm_config_force": "",
  "npm_config_dev": "",
  "npm_config_cache_lock_stale": "60000",
  "npm_config_package_lock": "true",
  "GTK_IM_MODULE": "ibus",
  "_": "/home/siegfried/.config/fnm/bin/node"
}

See ? The result is totally different, because npm injects some keys/values:

So dotenv is pretty cool but you can use the npm cli and a .npmrc file to have the same functionality.

Protip: is you use Yarn, a yarn run start will give you the same result as npm !

P.S.: I learned this thing with rmat0n or dun4n (I don’t remember which one ^^), thanks a lot for everything buddies !