Node.js applications often need configuration values that change between a local shell, a CI job, and a deployment target. A .env file gives a development process a repeatable set of environment variables without hard-coding those values into JavaScript source.

The built-in --env-file flag loads key-value pairs before the entry script runs, so application code reads them from process.env like any other environment variable. This startup-time path does not require the third-party dotenv package for a simple local configuration file.

Keep dotenv files trusted and local when they contain secrets. Existing shell environment values take precedence over file values, and the CLI env-file loader also parses Node startup options from NODE_OPTIONS, so a checked-in or untrusted file can change how the process starts.

Steps to load a .env file in Node.js:

  1. Create a local .env file with development settings.
    $ cat > .env <<'EOF'
    APP_ENV=development
    PORT=3000
    API_TOKEN="local-dev-token"
    EOF

    Do not commit a real .env file that contains tokens, passwords, private endpoints, or account identifiers. Keep a separate .env.example with nonsecret variable names when the project needs a template.

  2. Create app.mjs with required variable checks.
    app.mjs
    const required = ["APP_ENV", "PORT", "API_TOKEN"];
     
    for (const name of required) {
      if (!process.env[name]) {
        console.error(`missing ${name}`);
        process.exit(1);
      }
    }
     
    console.log(`environment=${process.env.APP_ENV}`);
    console.log(`port=${process.env.PORT}`);
    console.log("apiToken=loaded");

    Only the presence of API_TOKEN is printed; the token value stays out of terminal output.

  3. Verify Node.js loads the .env file before the script starts.
    $ node --env-file=.env app.mjs
    environment=development
    port=3000
    apiToken=loaded

    The env file path is resolved from the current working directory. Use a different path after --env-file= when the file is stored elsewhere.

  4. Run the script with a command-scoped override for PORT.
    $ PORT=4000 node --env-file=.env app.mjs
    environment=development
    port=4000
    apiToken=loaded

    An existing environment variable wins over the same key in the env file. The assignment syntax shown is for POSIX shells; use the equivalent syntax for the shell that starts the process.

  5. Use the optional env-file flag when a local override file may not exist.
    $ node --env-file=.env --env-file-if-exists=.env.local app.mjs
    .env.local not found. Continuing without it.
    environment=development
    port=3000
    apiToken=loaded

    Place an optional local override after the base file when values in .env.local should replace matching values from .env whenever that file is present.

  6. Remove the temporary files.
    $ rm .env app.mjs