This post is a summary of the differences between module.exports and exports in Node.js described in the following note: Node.js Module – exports vs module.exports.

The article comes from 2011 but then updated in 2014. You may want to take a look at the comments, they add valuable insights. I especially value the one from Adam Ahmed, and I decided to include it below for my own convenience.

module.exports vs exports

It might help clarify things to show how they are initialized. Essentially before your code runs, there is a code that runs like this:

var module = {...}; // stuff
var exports = module.exports = {};

So both variables initially point to the same empty Object, but of course can be reassigned to any other value instead. So if you reassign the exports variable, it doesn’t affect module.exports. Similarly, if you reassign module.exports, it no longer affects exports. They will be pointing at different values. What makes module.exports the “real deal” is that when someone require()s your module, require essential does this:

function require(moduleName) {
    var module = getModule(moduleName);
    return module.exports;
}

It might also help to say that module is the real deal more than module.exports is. Take this code for example:

var truth = module;
var notExports = module.exports;
truth.exports = { genre: ‘Rock’ };
notExports.genre = ‘Blues';

‘Rock’ will be exported. Since truth is pointing to module, it can make lasting changes to the exports that notExports can’t.