Most people advise against using global variables. If you want the same logger class in different modules you can do this

logger.js

  module.exports = new logger(customConfig);

foobar.js

  var logger = require('./logger');
  logger('barfoo');

If you do want a global variable you can do:

global.logger = new logger(customConfig);
Answer from Pickels on Stack Overflow
๐ŸŒ
Node.js
nodejs.org โ€บ api โ€บ globals.html
Global objects | Node.js v25.8.2 Documentation
Any modification of this data outside ... user or per request when used in the context of a server, it is shared across all users and requests. ... The MessageChannel class. See MessageChannel for more details. ... A browser-compatible implementation of <MessageEvent>. ... The MessagePort class. See MessagePort for more details. This variable may appear to be global but is ...
Discussions

javascript - GLOBAL data per HTTP/Session request?
if i'm right to understood your ... to make global variable in node js which can stored username ... Hi! Thanks for answering. I've thought of that, but the problem is how do you know which uniqueID that HTTP request is on? You have to have a varible telling the server which ID it is, and it's the same story all over again, we have to pass around that uniqueID. :-/. Should there be any build-in session ID that's unique per ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Global scope for every request in NodeJS Express
I have a basic express server that needs to store some global variables during each request handling. More in depth, request handling involves many operation that need to be stored in a variable su... More on stackoverflow.com
๐ŸŒ stackoverflow.com
What do you think of Global variable for storing information obtained from token
Donโ€™t do that. Create a context object with all that information. Add a context-aware logger, permission and other call-cache information. Pass the context to literally every single method. More on reddit.com
๐ŸŒ r/node
10
0
May 2, 2024
Node.js global variables - javascript
I asked here: Does Node.js require inheritance? And I was told that I can set variables to the global scope by leaving out the variable. This does not work for me. That is, the following does not m... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Top answer
1 of 5
7

Yes, with some caveats. You're looking for a module called continuation-local-storage.
This allows you to keep arbitrary data for the remainder of callbacks for the current request, and access it in a global fashion.
I wrote a blog post about it here. But the gist is this:

  1. Install cls: npm install --save continuation-local-storage
  2. Create a namespace for your app (at the top of the main file for your app)

    var createNamespace = require('continuation-local-storage').createNamespace, 
        namespace = createNamespace('myAppNamespace');
    
  3. Create a middleware that runs downstream functions in the cls (continuation-local-storage) namespace

    var getNamespace = require('continuation-local-storage').getNamespace,
        namespace = getNamespace('myAppNamespace'),
    
    app.use(function(req, res, next) {    
      // wrap the events from request and response
      namespace.bindEmitter(req);
      namespace.bindEmitter(res);
    
      // run following middleware in the scope of the namespace we created
      namespace.run(function() {
        namespace.set(โ€˜fooโ€™, 'a string data');
        next();
      });
    });
    
  4. Since you ran next within namespace.run, any downstream function can access data in the namespace

    var getNamespace = require('continuation-local-storage').getNamespace,
        namespace = getNamespace('myAppNamespace');
    
    // Some downstream function that doesn't have access to req...
    function doSomething() {
      var myData = namespace.get('foo');
      // myData will be 'a string data'
    }
    
  5. There is the caveat that certain modules can "lose" the context created by cls. This means that when you go to lookup 'foo' on the namespace, it won't have it. There are a few ways to deal with this, namely using another module like cls-redis, cls-q, or binding to the namespace.

2 of 5
1

Per request, I think what you're after could be done with ordinary closures. For example, you'd define your custom functions in module that takes a req argument:

util_funcs.js:

module.exports = function( req ){
  return {
    customFunctionThatRequiresReq: function(){ console.info( req ) },
    otherFunctionThatRequiresReq:  function(){ console.log( req ) }
  };
};

Then wherever you depend on those functions (presumably some middleware elsewhere in the application), you can just require them in context:

var someMiddleWare = function( req, res, next ){

  var utils = require( 'util_funcs.js' )( req );

  utils.customFunctionThatRequiresReq();
  utils.otherFunctionThatRequiresReq();

}; 

This allows you to avoid littering your function args with req, and no dubious globals.

๐ŸŒ
Stack Abuse
stackabuse.com โ€บ using-global-variables-in-node-js
Using Global Variables in Node.js
July 8, 2024 - Now that we have a better understanding of what a global variable in Node is, let's talk about how we actually set up and use a global variable. To set up a global variable, we need to create it on the global object. The global object is what gives us the scope of the entire project, rather ...
Top answer
1 of 4
14

Here is my suggestion avoid global state like fire.

  • It's the number one maintenance problem in Node servers from my experience.
  • It makes your code not composable and harder to reuse.
  • It creates implicit dependencies in your code - you're never sure which piece depends on which and it's not easy to verify.

You want the parts of code that each piece of an application uses to be as explicit as possible. It's a huge issue.

The issue

We want to synchronize state across multiple requests and act accordingly. This is a very big problem in writing software - some say even the biggest. The importance of the way objects in the application communicate can not be overestimated.

Some solutions

There are several ways to accomplish sharing state across requests or server wide in a Node server. It depends on what you want to do. Here are the two most common imo.

  1. I want to observe what the requests do.
  2. I want one request to do things based on what another request did.

1. I want to observe what the requests do

Again, there are many ways to do this. Here are the two I see most.

Using an event emitter

This way requests emit events. The application reads events the requests fire and learns about them accordingly. The application itself could be an event emitter you can observe from the outside.

You can do something like:

request.emit("Client did something silly", theSillyThing);

And then listen to it from the outside if you choose to.

Using an observer pattern

This is like an event emitter but reversed. You keep a list of dependencies on the request and call a handler method on them yourself when something interesting happens on the request.

Personally, I usually prefer an event emitter because I think they usually solve the case better.

2. I want one request to do things based on what another request did.

This is a lot tricker than just listening. again, there are several approaches here. What they have in common is that we put the sharing in a service

Instead of having global state - each request gets access to a service - for example when you read a file you notify the service and when you want a list of read files - you ask the service. Everything is explicit in the dependency.

The service is not global, only dependencies of it. For example, it can coordinate resources and the data, being some form of Repository).

Nice theory! Now what about my use case?

Here are two options for what I would do in your case. It's far from the only solution.

First option:

  • Each of the modules are an event emitter, whenever they read a file they emit an event.
  • A service listens to all their events and keeps count.
  • Requests have access to that service explicitly and can query it for a list of files.
  • Requests perform writes through the modules themselves and not the added service.

Second option:

  • Create a service that owns a copy of module1, module2 and module3. (composition)
  • The service delegates actions to the modules based on what is required from it.
  • The service keeps the list of files accessed since the requests were made through it.
  • The request stops using the modules directly - uses the service instead.

Both these approaches have advantages and disadvantages. A more complicated solution might be required (those two are in practice pretty simple to do) where the services are abstracted further but I think this is a good start.

2 of 4
0

One simple way is storing data on the request object.

Here is an example (using Express):

app.get('/hello.txt', function(req, res){
    req.transaction = req.transaction || [];

    if (req.transaction.length) {
        // something else has already written to this array
    }
});

However, I don't really see how you can need this. When you call moduleA or moduleB, you just have to pass an object as argument, and it solves your issue. Maybe you're looking for dependency injection?

๐ŸŒ
Speakingjs
speakingjs.com โ€บ es5 โ€บ ch16.html
Chapter 16. Variables: Scopes, Environments, and Closures
Browsers include window, which is standardized as part of the Document Object Model (DOM), not as part of ECMAScript 5. There is one global object per frame or window. Node.js contains global, which is a Node.js-specific variable. Each module has its own scope in which this points to an object ...
Find elsewhere
๐ŸŒ
Mastering JS
masteringjs.io โ€บ tutorials โ€บ fundamentals โ€บ global-variable
Global Variables in JavaScript - Mastering JS
February 2, 2021 - If you assign to an variable that you didn't define using let, const, or var outside of strict mode, that automatically becomes a global variable. function() { answer = 42; // `answer` becomes global scoped in the browser, or file scoped in Node.js }
Top answer
1 of 7
242

You can use global like so:

global._ = require('underscore')
2 of 7
221

In Node.js, you can set global variables via the "global" or "GLOBAL" object:

GLOBAL._ = require('underscore'); // But you "shouldn't" do this! (see note below)

or more usefully...

GLOBAL.window = GLOBAL;  // Like in the browser

From the Node.js source, you can see that these are aliased to each other:

node-v0.6.6/src/node.js:
28:     global = this;
128:    global.GLOBAL = global;

In the code above, "this" is the global context. With the CommonJS module system (which Node.js uses), the "this" object inside of a module (i.e., "your code") is not the global context. For proof of this, see below where I spew the "this" object and then the giant "GLOBAL" object.

console.log("\nTHIS:");
console.log(this);
console.log("\nGLOBAL:");
console.log(global);

/* Outputs ...

THIS:
{}

GLOBAL:
{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Int16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Uint16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Int32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Uint32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float64Array: { [Function] BYTES_PER_ELEMENT: 8 },
  DataView: [Function: DataView],
  global: [Circular],
  process:
   { EventEmitter: [Function: EventEmitter],
     title: 'node',
     assert: [Function],
     version: 'v0.6.5',
     _tickCallback: [Function],
     moduleLoadList:
      [ 'Binding evals',
        'Binding natives',
        'NativeModule events',
        'NativeModule buffer',
        'Binding buffer',
        'NativeModule assert',
        'NativeModule util',
        'NativeModule path',
        'NativeModule module',
        'NativeModule fs',
        'Binding fs',
        'Binding constants',
        'NativeModule stream',
        'NativeModule console',
        'Binding tty_wrap',
        'NativeModule tty',
        'NativeModule net',
        'NativeModule timers',
        'Binding timer_wrap',
        'NativeModule _linklist' ],
     versions:
      { node: '0.6.5',
        v8: '3.6.6.11',
        ares: '1.7.5-DEV',
        uv: '0.6',
        openssl: '0.9.8n' },
     nextTick: [Function],
     stdout: [Getter],
     arch: 'x64',
     stderr: [Getter],
     platform: 'darwin',
     argv: [ 'node', '/workspace/zd/zgap/darwin-js/index.js' ],
     stdin: [Getter],
     env:
      { TERM_PROGRAM: 'iTerm.app',
        'COM_GOOGLE_CHROME_FRAMEWORK_SERVICE_PROCESS/USERS/DDOPSON/LIBRARY/APPLICATION_SUPPORT/GOOGLE/CHROME_SOCKET': '/tmp/launch-nNl1vo/ServiceProcessSocket',
        TERM: 'xterm',
        SHELL: '/bin/bash',
        TMPDIR: '/var/folders/2h/2hQmtmXlFT4yVGtr5DBpdl9LAiQ/-Tmp-/',
        Apple_PubSub_Socket_Render: '/tmp/launch-9Ga0PT/Render',
        USER: 'ddopson',
        COMMAND_MODE: 'unix2003',
        SSH_AUTH_SOCK: '/tmp/launch-sD905b/Listeners',
        __CF_USER_TEXT_ENCODING: '0x12D732E7:0:0',
        PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:~/bin:/usr/X11/bin',
        PWD: '/workspace/zd/zgap/darwin-js',
        LANG: 'en_US.UTF-8',
        ITERM_PROFILE: 'Default',
        SHLVL: '1',
        COLORFGBG: '7;0',
        HOME: '/Users/ddopson',
        ITERM_SESSION_ID: 'w0t0p0',
        LOGNAME: 'ddopson',
        DISPLAY: '/tmp/launch-l9RQXI/org.x:0',
        OLDPWD: '/workspace/zd/zgap/darwin-js/external',
        _: './index.js' },
     openStdin: [Function],
     exit: [Function],
     pid: 10321,
     features:
      { debug: false,
        uv: true,
        ipv6: true,
        tls_npn: false,
        tls_sni: true,
        tls: true },
     kill: [Function],
     execPath: '/usr/local/bin/node',
     addListener: [Function],
     _needTickCallback: [Function],
     on: [Function],
     removeListener: [Function],
     reallyExit: [Function],
     chdir: [Function],
     debug: [Function],
     error: [Function],
     cwd: [Function],
     watchFile: [Function],
     umask: [Function],
     getuid: [Function],
     unwatchFile: [Function],
     mixin: [Function],
     setuid: [Function],
     setgid: [Function],
     createChildProcess: [Function],
     getgid: [Function],
     inherits: [Function],
     _kill: [Function],
     _byteLength: [Function],
     mainModule:
      { id: '.',
        exports: {},
        parent: null,
        filename: '/workspace/zd/zgap/darwin-js/index.js',
        loaded: false,
        exited: false,
        children: [],
        paths: [Object] },
     _debugProcess: [Function],
     dlopen: [Function],
     uptime: [Function],
     memoryUsage: [Function],
     uvCounters: [Function],
     binding: [Function] },
  GLOBAL: [Circular],
  root: [Circular],
  Buffer:
   { [Function: Buffer]
     poolSize: 8192,
     isBuffer: [Function: isBuffer],
     byteLength: [Function],
     _charsWritten: 8 },
  setTimeout: [Function],
  setInterval: [Function],
  clearTimeout: [Function],
  clearInterval: [Function],
  console: [Getter],
  window: [Circular],
  navigator: {} }
*/

** Note: regarding setting "GLOBAL._", in general you should just do var _ = require('underscore');. Yes, you do that in every single file that uses Underscore.js, just like how in Java you do import com.foo.bar;. This makes it easier to figure out what your code is doing because the linkages between files are 'explicit'. It is mildly annoying, but a good thing. .... That's the preaching.

There is an exception to every rule. I have had precisely exactly one instance where I needed to set "GLOBAL._". I was creating a system for defining "configuration" files which were basically JSON, but were "written in JavaScript" to allow a bit more flexibility. Such configuration files had no 'require' statements, but I wanted them to have access to Underscore.js (the entire system was predicated on Underscore.js and Underscore.js templates), so before evaluating the "configuration", I would set "GLOBAL._". So yeah, for every rule, there's an exception somewhere. But you had better have a darn good reason and not just "I get tired of typing 'require', so I want to break with the convention".

๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ node.js โ€บ how-to-create-global-variables-accessible-in-all-views-using-express-nodejs
How to Create Global Variables Accessible in all Views using Express/NodeJS ? - GeeksforGeeks
April 9, 2024 - This approach is useful for passing dynamic data to views based on each request, such as user authentication status or request-specific information. Example: Illustration to create global variable using res.locals ...
๐ŸŒ
Quora
quora.com โ€บ How-do-I-declare-a-global-variable-in-Node
How to declare a global variable in Node - Quora
Answer (1 of 2): Generally you don't want to. If you think you want to, then rethink your plan and don't do it. For instance, if you need a value shared between modules, your can export it from one and import it where it's needed. But the way to actually add something to the global namespace i...
๐ŸŒ
EDUCBA
educba.com โ€บ home โ€บ software development โ€บ software development tutorials โ€บ javascript technology tutorial โ€บ node.js global variable
Node.js Global Variable | How Global Variable Work in Node.js?
March 29, 2023 - So in node js, we have one object called global. So whatever function we are using in nodejs without creating them is coming from this global object. One thing to note here, if we are declaring any variable in nodejs, then it is not added to its global scope.
Call ย  +917738666252
Address ย  Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
๐ŸŒ
Andycarter
andycarter.dev โ€บ blog โ€บ variable-scope-in-modern-javascript
Variable Scope in Modern JavaScript with var, let and const โ€“ Andy Carter
August 18, 2018 - If you use var foobar in a NodeJS module it is local to that module. To define a global variable in NodeJS we need to use the global namespace object, global.
๐ŸŒ
Node.js
nodejs.org โ€บ download โ€บ release โ€บ v14.16.1 โ€บ docs โ€บ api โ€บ globals.html
Global objects | Node.js v14.16.1 Documentation
In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different.
๐ŸŒ
Node.js
nodejs.org โ€บ download โ€บ release โ€บ v12.13.0 โ€บ docs โ€บ api โ€บ globals.html
Global Objects | Node.js v12.13.0 Documentation
In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different.
๐ŸŒ
GitHub
gist.github.com โ€บ arsho โ€บ edcd784c6228d0635a5b8e3907c5c95b
This little script saves a global variable in express js. It count how many times an user visit the root of the website which is in this case http://localhost:3000/ ยท GitHub
January 13, 2017 - This little script saves a global variable in express js. It count how many times an user visit the root of the website which is in this case http://localhost:3000/ - global_variable_express.js
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ node-js-global-objects
NodeJS Global Objects | GeeksforGeeks
March 18, 2025 - In browser-based JavaScript, the window object is the global scope, meaning it holds all global variables and functions. In NodeJS, instead of the window obje ... In NodeJS, modules play an important role in organizing, structuring, and reusing code efficiently. A module is a self-contained block of code that can be exported and imported into different parts of an application. This modular approach helps developers manage large projects, making them more scal ... A local module in Node.js refers to a custom module created in an application.