Environment Variable Options

Options can be populated from environment variables in two ways:

Per-option env key — set env: 'MY_VAR' on any individual option. No .env() call is needed. Only the options you annotate can read from the environment; everything else stays CLI-flag-only.

Global .env() call — enables environment variable support for every option at once, automatically deriving the variable name from the option name and using the CLI name as a prefix (e.g. greet-app → GREET_APP).

In both cases, command-line flags take precedence over environment variables, which in turn take precedence over config files and defaults.

Per-option environment variables

The simplest way to make a single option env-configurable is to add an env key directly to its definition. No .env() call is required — the parser reads from the named variable whenever the flag is absent on the command line.

1import cli from 'cli-forge';
2
3// Without calling .env(), environment variable support is opt-in per option.
4// Only options with an explicit `env` key can be populated from the environment —
5// every other option can only be set via command-line flags.
6const app = cli('greet-app').command('hello', {
7  builder: (args) =>
8    args
9      .option('name', {
10        type: 'string',
11        required: true,
12        description: 'Name to greet',
13        // Reads from the GREET_NAME environment variable.
14        // The key you provide here is used as-is (no prefix is applied).
15        // camelCase, dashed-case, and UPPER_SNAKE_CASE are all accepted.
16        env: 'GREET_NAME',
17      })
18      .option('greeting', {
19        type: 'string',
20        default: 'Hello',
21        description: 'Greeting word to use',
22        env: 'GREET_GREETING',
23      })
24      .option('verbose', {
25        type: 'boolean',
26        default: false,
27        description: 'Print extra details',
28        // No `env` key — this option cannot be set from the environment.
29        // It can only be passed as --verbose on the command line.
30      }),
31  handler: (args) => {
32    if (args.verbose) {
33      console.log('Verbose mode enabled');
34    }
35    console.log(`${args.greeting}, ${args.name}!`);
36  },
37});
38
39export default app;
40
41if (require.main === module) {
42  app.forge();
43}

The exact string you provide becomes the environment variable name. No prefix is applied, so env: 'PORT' reads from PORT, not GREET_APP_PORT. Options that have no env key — like --verbose above — cannot be set from the environment at all, which is useful for flags that should only be passed explicitly by the caller.

Global environment variable support

Calling .env() turns on environment variable support for every option in one go. cli-forge converts the CLI name to UPPER_SNAKE_CASE and uses it as a prefix, then appends the option name in the same format.

1import cli from 'cli-forge';
2
3// Calling .env() enables environment variable support for every option at once.
4// The CLI name is converted to UPPER_SNAKE_CASE and used as a prefix, so the
5// CLI named "greet-app" produces the prefix "GREET_APP".
6//
7// For example:
8//   --name     reads from GREET_APP_NAME
9//   --greeting reads from GREET_APP_GREETING
10const app = cli('greet-app')
11  .env()
12  .command('hello', {
13    builder: (args) =>
14      args
15        .option('name', {
16          type: 'string',
17          required: true,
18          description: 'Name to greet',
19        })
20        .option('greeting', {
21          type: 'string',
22          default: 'Hello',
23          description: 'Greeting word to use',
24        }),
25    handler: (args) => {
26      console.log(`${args.greeting}, ${args.name}!`);
27    },
28  });
29
30export default app;
31
32if (require.main === module) {
33  app.forge();
34}

With a CLI named greet-app, the auto-derived variable names are:

OptionEnvironment variable
--nameGREET_APP_NAME
--greetingGREET_APP_GREETING

You can still override the key for a specific option by providing env: 'MY_KEY' on that option, or opt a single option out of env support with env: false.


All Example Files

FILE EXPLORER
content.md
1## Per-option environment variables
2
3The simplest way to make a single option env-configurable is to add an `env`
4key directly to its definition. No `.env()` call is required — the parser
5reads from the named variable whenever the flag is absent on the command line.
6
7<%= file('per-option-env.ts') %>
8
9The exact string you provide becomes the environment variable name. No prefix
10is applied, so `env: 'PORT'` reads from `PORT`, not `GREET_APP_PORT`. Options
11that have no `env` key — like `--verbose` above — cannot be set from the
12environment at all, which is useful for flags that should only be passed
13explicitly by the caller.
14
15## Global environment variable support
16
17Calling `.env()` turns on environment variable support for every option in one
18go. cli-forge converts the CLI name to `UPPER_SNAKE_CASE` and uses it as a
19prefix, then appends the option name in the same format.
20
21<%= file('with-global-env.ts') %>
22
23With a CLI named `greet-app`, the auto-derived variable names are:
24
25| Option | Environment variable |
26|--------|----------------------|
27| `--name` | `GREET_APP_NAME` |
28| `--greeting` | `GREET_APP_GREETING` |
29
30You can still override the key for a specific option by providing `env: 'MY_KEY'`
31on that option, or opt a single option out of env support with `env: false`.
32