How to Set Node Environment Variables in Code: The Complete Developer Guide
You can set Node environment variables in code by assigning values to properties on the global process.env object, which stores all values as strings and isolates changes to the current process only.
Setting Node environment variables programmatically is essential for configuring runtime behavior without relying on external shell commands. In the nodejs/node repository, the global process.env object—defined in lib/process.js and implemented natively in src/process_wrap.cc—provides direct access to the environment, allowing you to read, set, and delete variables dynamically within your application.
Understanding the process.env Object
The process.env object is a global singleton that acts like a plain JavaScript object mapping environment variable names to their string values. According to the source code in lib/process.js, this object is a proxy to the underlying system environment, with all property access and assignment operations handled by the Node.js runtime.
Key characteristics include:
- String coercion: All assigned values are automatically converted to strings (though implicit conversion is deprecated and may throw in future versions).
- Process isolation: Modifications affect only the current Node.js process and child processes explicitly spawned with
env: process.env. - Platform differences: On Windows, environment variable names are case-insensitive; on POSIX systems (Linux, macOS), they are case-sensitive.
How to Set Node Environment Variables in Code
Basic Assignment
To set an environment variable, assign a value directly to a property on process.env:
// Set a variable
process.env.API_KEY = 'sk-1234567890abcdef';
// Read it back
console.log(process.env.API_KEY); // → sk-1234567890abcdef
This assignment immediately updates the environment for the current process. The change persists for the lifetime of the process unless explicitly deleted.
Handling Non-String Values
While process.env accepts non-string values, Node.js converts them to strings automatically. However, this implicit conversion is deprecated according to the documentation in doc/api/process.md, and explicit string conversion is recommended:
// Implicit conversion (deprecated behavior)
process.env.PORT = 3000; // stored as "3000"
process.env.DEBUG = true; // stored as "true"
// Explicit conversion (recommended)
process.env.PORT = String(3000);
process.env.DEBUG = String(true);
console.log(typeof process.env.PORT); // "string"
Deleting Environment Variables
Remove variables using the delete operator:
process.env.TEMP_VAR = 'temporary';
console.log(process.env.TEMP_VAR); // → temporary
delete process.env.TEMP_VAR;
console.log(process.env.TEMP_VAR); // → undefined
Working with Child Processes and Worker Threads
Propagating Variables to Child Processes
Environment variables set in the parent process are not automatically inherited by child processes unless explicitly passed. Use the env option in spawn, exec, or fork:
const { spawn } = require('node:child_process');
// Set in parent
process.env.CHILD_MODE = 'production';
// Pass to child explicitly
const child = spawn('node', ['-e', 'console.log(process.env.CHILD_MODE)'], {
stdio: 'inherit',
env: process.env // Propagates the modified environment
});
Environment Isolation in Worker Threads
Worker threads receive their own copy of process.env. Mutations in a worker do not affect the main thread or other workers, as shown in the test files under test/worker_threads:
const { Worker } = require('node:worker_threads');
// Main thread sets variable
process.env.WORKER_VAR = 'main';
const worker = new Worker(`
const { parentPort } = require('node:worker_threads');
console.log('Worker sees:', process.env.WORKER_VAR); // undefined
// Set in worker (isolated)
process.env.WORKER_VAR = 'worker';
parentPort.postMessage(process.env.WORKER_VAR);
`, { eval: true });
worker.on('message', (msg) => console.log('Worker sent back:', msg));
// Main thread value remains 'main'
Platform-Specific Behavior
Environment variable handling differs between Windows and POSIX systems:
Windows (Case-Insensitive)
process.env.Foo = 'bar';
console.log(process.env.FOO); // → "bar" (same on Windows)
POSIX Linux/macOS (Case-Sensitive)
process.env.Foo = 'bar';
console.log(process.env.FOO); // → undefined (different variable)
This behavior is implemented in the native layer (src/process_wrap.cc) and documented in doc/api/process.md.
Summary
- Set variables by assigning to
process.env.VAR_NAME = 'value'—all values store as strings. - Read variables using
process.env.VAR_NAMEorprocess.env['VAR_NAME']for dynamic names. - Delete variables with
delete process.env.VAR_NAMEto remove them from the environment. - Child processes require explicit
env: process.envin spawn options to inherit modifications. - Worker threads isolate
process.envcopies—mutations in workers don't affect the main thread. - Platform differences matter: Windows treats environment variables as case-insensitive; POSIX systems treat them as case-sensitive.
Frequently Asked Questions
Does setting process.env modify the parent shell's environment?
No. Changes to process.env affect only the current Node.js process and any child processes you explicitly spawn with the modified environment. The parent shell or other running processes remain unaffected because Node.js cannot modify the environment of already-running parent processes.
Can I store numbers and booleans in process.env?
While you can assign numbers and booleans directly, Node.js converts them to strings automatically. According to the source code in src/process_wrap.cc, implicit non-string assignment is deprecated and may throw an error in future versions. Always use explicit string conversion: process.env.PORT = String(3000).
Are environment variables shared between worker threads?
No. Each worker thread receives its own copy of process.env when instantiated. Mutations made inside a worker thread are isolated from the main thread and other workers unless you explicitly pass a custom env object to the Worker constructor. This isolation is tested in the test/worker_threads directory of the Node.js source.
Is process.env case-sensitive on all platforms?
No. On Windows, environment variable names are case-insensitive, so process.env.Foo and process.env.FOO reference the same variable. On POSIX platforms (Linux, macOS, BSD), environment variables are case-sensitive, making Foo and FOO distinct variables. This behavior is defined in the platform-specific implementations within src/process_wrap.cc.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →