@@ -2309,6 +2309,227 @@ import { loadEnvFile } from 'node:process';
2309
2309
loadEnvFile ();
2310
2310
` ` `
2311
2311
2312
+ ### Environment variables file parsing specification
2313
+
2314
+ This section describes how the environment variables file parsing reads a file
2315
+ and sets up the environment variables in Node.js.
2316
+ While ` .env ` files descend from shell scripts that export environment
2317
+ variables, there are important distinctions in how they handle quoting,
2318
+ spacing, and escaping values.
2319
+ Additionally, the [Dotenv][] package has played a significant role in
2320
+ popularizing this format.
2321
+
2322
+ #### Basic parsing
2323
+
2324
+ * The parser reads line by line, splitting each line into a key and a value
2325
+ at the first ` = ` sign.
2326
+ * Lines without an ` = ` are ignored.
2327
+
2328
+ ` ` ` bash
2329
+ BASIC = basic
2330
+ WITHOUT_EQUAL
2331
+ ` ` `
2332
+
2333
+ ` ` ` cjs
2334
+ const assert = require (' node:assert' );
2335
+ const process = require (' node:process' );
2336
+ assert .strictEqual (process .env .BASIC , ' basic' );
2337
+ assert .strictEqual (process .env .WITHOUT_EQUAL , undefined );
2338
+ ` ` `
2339
+
2340
+ ` ` ` mjs
2341
+ import assert from ' node:assert' ;
2342
+ import process from ' node:process' ;
2343
+ assert .strictEqual (process .env .BASIC , ' basic' );
2344
+ assert .strictEqual (process .env .WITHOUT_EQUAL , undefined );
2345
+ ` ` `
2346
+
2347
+ #### Whitespace handling
2348
+
2349
+ * Leading and trailing whitespaces characters around keys and values are
2350
+ ignored unless they are enclosed within quotes.
2351
+
2352
+ ` ` ` bash
2353
+ SPACED_KEY = parsed
2354
+ ` ` `
2355
+
2356
+ ` ` ` cjs
2357
+ const assert = require (' node:assert' );
2358
+ const process = require (' node:process' );
2359
+ assert .strictEqual (process .env .SPACED_KEY , ' parsed' );
2360
+ ` ` `
2361
+
2362
+ ` ` ` mjs
2363
+ import assert from ' node:assert' ;
2364
+ import process from ' node:process' ;
2365
+ assert .strictEqual (process .env .SPACED_KEY , ' parsed' );
2366
+ ` ` `
2367
+
2368
+ #### Comments
2369
+
2370
+ * Lines starting with ` #` are treated as comments and ignored.
2371
+ * Inline comments (starting with ` #` after a value) are ignored, and do not
2372
+ affect parsing of the value.
2373
+
2374
+ ` ` ` bash
2375
+ # COMMENTS = work
2376
+ INLINE_COMMENTS = inline comments # work
2377
+ ` ` `
2378
+
2379
+ ` ` ` cjs
2380
+ const assert = require (' node:assert' );
2381
+ const process = require (' node:process' );
2382
+ assert .strictEqual (process .env .COMMENTS , undefined );
2383
+ assert .strictEqual (process .env .INLINE_COMMENTS , ' inline comments' );
2384
+ ` ` `
2385
+
2386
+ ` ` ` mjs
2387
+ import assert from ' node:assert' ;
2388
+ import process from ' node:process' ;
2389
+ assert .strictEqual (process .env .COMMENTS , undefined );
2390
+ assert .strictEqual (process .env .INLINE_COMMENTS , ' inline comments' );
2391
+ ` ` `
2392
+
2393
+ #### Empty values
2394
+
2395
+ * Variables with no value assigned (just a key followed by ` = ` ) are set to
2396
+ an empty string.
2397
+
2398
+ ` ` ` bash
2399
+ EMPTY =
2400
+ ` ` `
2401
+
2402
+ ` ` ` cjs
2403
+ const assert = require (' node:assert' );
2404
+ const process = require (' node:process' );
2405
+ assert .strictEqual (process .env .EMPTY , ' ' );
2406
+ ` ` `
2407
+
2408
+ ` ` ` mjs
2409
+ import assert from ' node:assert' ;
2410
+ import process from ' node:process' ;
2411
+ assert .strictEqual (process .env .EMPTY , ' ' );
2412
+ ` ` `
2413
+
2414
+ #### Quoted values
2415
+
2416
+ * Single (` ' `), double (`"`), and backtick (`` ` ``) quotes are recognized.
2417
+ The content within the quotes is taken as is, including leading and
2418
+ trailing spaces.
2419
+ * Quotes within a different quote type are preserved.
2420
+
2421
+ ```bash
2422
+ FIRST_NAME=' John '
2423
+ MIXED_QUOTES="Say ' Hello! ' "
2424
+ BACKTICK_IN_QUOTES="Using `backticks` in double quotes"
2425
+ ```
2426
+
2427
+ ```cjs
2428
+ const assert = require(' node: assert' );
2429
+ const process = require(' node: process ' );
2430
+ assert.strictEqual(process.env.FIRST_NAME, ' John ' );
2431
+ assert.strictEqual(process.env.MIXED_QUOTES, "Say ' Hello! ' ");
2432
+ assert.strictEqual(process.env.BACKTICK_IN_QUOTES,
2433
+ ' Using ` backticks` in double quotes' );
2434
+ ```
2435
+
2436
+ ```mjs
2437
+ import assert from ' node: assert' ;
2438
+ import process from ' node: process ' ;
2439
+ assert.strictEqual(process.env.FIRST_NAME, ' John ' );
2440
+ assert.strictEqual(process.env.MIXED_QUOTES, "Say ' Hello! ' ");
2441
+ assert.strictEqual(process.env.BACKTICK_IN_QUOTES,
2442
+ ' Using ` backticks` in double quotes' );
2443
+ ```
2444
+
2445
+ #### Multiline values
2446
+
2447
+ * Values enclosed in quotes described above that span multiple
2448
+ lines are accepted and stored with newline characters.
2449
+
2450
+ ```bash
2451
+ MULTI_DOUBLE_QUOTED="double
2452
+ quoted"
2453
+
2454
+ MULTI_SINGLE_QUOTED=' single
2455
+ quoted'
2456
+
2457
+ MULTI_BACKTICKED=`this
2458
+ "multiline"
2459
+ value`
2460
+ ```
2461
+
2462
+ ```cjs
2463
+ const assert = require(' node: assert' );
2464
+ const process = require(' node: process ' );
2465
+ assert.strictEqual(process.env.MULTI_DOUBLE_QUOTED, ' double\nquoted' );
2466
+ assert.strictEqual(process.env.MULTI_SINGLE_QUOTED, ' single\nquoted' );
2467
+ assert.strictEqual(process.env.MULTI_BACKTICKED,
2468
+ ' this \n" multiline" \nvalue' );
2469
+ ```
2470
+
2471
+ ```mjs
2472
+ import assert from ' node: assert' ;
2473
+ import process from ' node: process ' ;
2474
+ assert.strictEqual(process.env.MULTI_DOUBLE_QUOTED, ' double\nquoted' );
2475
+ assert.strictEqual(process.env.MULTI_SINGLE_QUOTED, ' single\nquoted' );
2476
+ assert.strictEqual(process.env.MULTI_BACKTICKED,
2477
+ ' this \n" multiline" \nvalue' );
2478
+ ```
2479
+
2480
+ #### Escapes
2481
+
2482
+ * Newlines in double-quoted values are expanded to newline characters.
2483
+ * Other escapes (e.g., `\n `) are treated as literal text in single-quoted
2484
+ or unquoted values.
2485
+
2486
+ ```bash
2487
+ EXPAND_NEWLINES="expand\n new\n lines"
2488
+ DONT_EXPAND_UNQUOTED=dontexpand\n newlines
2489
+ DONT_EXPAND_SQUOTED=' dontexpand\nnewlines'
2490
+ ```
2491
+
2492
+ ```cjs
2493
+ const assert = require(' node: assert' );
2494
+ const process = require(' node: process ' );
2495
+ assert.strictEqual(process.env.EXPAND_NEWLINES, ' expand\nnew\nlines' );
2496
+ assert.strictEqual(process.env.DONT_EXPAND_UNQUOTED,
2497
+ ' dontexpand\\nnewlines' );
2498
+ assert.strictEqual(process.env.DONT_EXPAND_SQUOTED,
2499
+ ' dontexpand\\nnewlines' );
2500
+ ```
2501
+
2502
+ ```mjs
2503
+ import assert from ' node: assert' ;
2504
+ import process from ' node: process ' ;
2505
+ assert.strictEqual(process.env.EXPAND_NEWLINES, ' expand\nnew\nlines' );
2506
+ assert.strictEqual(process.env.DONT_EXPAND_UNQUOTED,
2507
+ ' dontexpand\\nnewlines' );
2508
+ assert.strictEqual(process.env.DONT_EXPAND_SQUOTED,
2509
+ ' dontexpand\\nnewlines' );
2510
+ ```
2511
+
2512
+ #### Export statements
2513
+
2514
+ * Any `export` keyword before a key is ignored, allowing compatibility with
2515
+ shell scripts. The line is parsed as if `export` weren' t there.
2516
+
2517
+ ` ` ` bash
2518
+ export EXPORT_EXAMPLE = ignore export
2519
+ ` ` `
2520
+
2521
+ ` ` ` cjs
2522
+ const assert = require('node:assert');
2523
+ const process = require('node:process');
2524
+ assert.strictEqual(process.env.EXPORT_EXAMPLE, 'ignore export');
2525
+ ` ` `
2526
+
2527
+ ` ` ` mjs
2528
+ import assert from 'node:assert';
2529
+ import process from 'node:process';
2530
+ assert.strictEqual(process.env.EXPORT_EXAMPLE, 'ignore export');
2531
+ ` ` `
2532
+
2312
2533
## ` process.mainModule`
2313
2534
2314
2535
<!-- YAML
@@ -3995,6 +4216,7 @@ cases:
3995
4216
[Android building]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md#androidandroid-based-devices-eg-firefox-os
3996
4217
[Child Process]: child_process.md
3997
4218
[Cluster]: cluster.md
4219
+ [Dotenv]: https://github.com/motdotla/dotenv
3998
4220
[Duplex]: stream.md#duplex-and-transform-streams
3999
4221
[Event Loop]: https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#understanding-processnexttick
4000
4222
[LTS]: https://github.com/nodejs/Release
0 commit comments