Skip to content

Pass multiple .env files on the CLIΒ #1248

Closed

Description

@Lenni009

Describe the feature

In Nuxt v4.3.0, you could pass multiple .env files on the CLI like this:

nuxt dev --dotenv .env.development --dotenv .env.local

Since Nuxt v4.3.1, this no longer works and only one --dotenv argument is accepted.

There may be cases where someone wants to use multiple files, for example a .env.local for sensitive API keys and a .env.development for non-sensitive configuration data like DB URLs.

Since the config in .env.development is only for dev and would result in a broken application in prod, it doesn't make much sense semantically to put its contents into a .env file.

The solution could be implemented with a separator, like this (although I have to admit it looks a bit ugly):

nuxt dev --dotenv .env.development,.env.local

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module?

Final checks

Activity

  1. OrbisK commented on Mar 13, 2026

    @OrbisK
    Member

    This might be an upstream issue at https://github.com/unjs/citty

  2. transferred this issue fromnuxt/nuxton Mar 13, 2026
  3. antonyharfield commented on May 18, 2026

    @antonyharfield

    It is an upstream issue... citty v0.2.0 replaced its custom parser with Node.js's native util.parseArgs.


    Workaround

    Use dotenv-cli and pass in your list of env files:

    dotenv -e .env.development -e .env -- nuxt dev
    

    Root Cause Analysis

    The bug has three layers, each responsible to a different package.

    Layer 1 β€” node:util.parseArgs: the multiple flag

    Node.js's built-in util.parseArgs (introduced in v18.3, stable in v20) has a multiple option per argument. When it's false (the default), repeated flags use last-wins semantics:

    --dotenv .env --dotenv .env.development  β†’  { dotenv: '.env.development' }
    

    When multiple: true, all values are collected into an array:

    --dotenv .env --dotenv .env.development  β†’  { dotenv: ['.env', '.env.development'] }
    

    Layer 2 β€” citty 0.2.x: never sets multiple: true

    In citty v0.2.0, the custom arg parser was replaced with node:util.parseArgs. The problem is that in _parser.ts, when citty builds the options object passed to util.parseArgs, it never sets multiple: true for any arg type. You can see exactly this in the source:

    // From citty's parseRawArgs() in dist/index.mjs
    for (const name of allOptions) {
      if (!options[name]) options[name] = {
        type: getType(name),    // 'boolean' or 'string'
        default: defaults[name]
        // ← no `multiple: true` ever
      };
    }

    Before v0.2.0, citty had its own hand-rolled parser that accumulated repeated flags into arrays. The switch to util.parseArgs silently dropped that behavior.

    Layer 3 β€” nuxi (@nuxt/cli): dotenv defined as plain type: "string"

    In nuxi's shared args definition:

    // node_modules/nuxi/dist/_shared-*.mjs
    const dotEnvArgs = {
      dotenv: {
        type: "string",
        description: "Path to `.env` file to load, relative to the root directory"
      }
    };

    dotenv is a plain string arg with no indication that it should be repeatable. Even if citty did support a multiple field, nuxi doesn't set it.

  4. added theissue type on Jul 25, 2026
  5. danielroe commented on Jul 27, 2026

    @danielroe
    Member

    this will need unjs/citty#258 to be implemented first. possibly via unjs/citty#259.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions