The export default {...} construction is just a shortcut for something like this:

const funcs = {
    foo() { console.log('foo') }, 
    bar() { console.log('bar') },
    baz() { foo(); bar() }
}

export default funcs

It must become obvious now that there are no foo, bar or baz functions in the module's scope. But there is an object named funcs (though in reality it has no name) that contains these functions as its properties and which will become the module's default export.

So, to fix your code, re-write it without using the shortcut and refer to foo and bar as properties of funcs:

const funcs = {
    foo() { console.log('foo') }, 
    bar() { console.log('bar') },
    baz() { funcs.foo(); funcs.bar() } // here is the fix
}

export default funcs

Another option is to use this keyword to refer to funcs object without having to declare it explicitly, as @pawel has pointed out.

Yet another option (and the one which I generally prefer) is to declare these functions in the module scope. This allows to refer to them directly:

function foo() { console.log('foo') }
function bar() { console.log('bar') }
function baz() { foo(); bar() }

export default {foo, bar, baz}

And if you want the convenience of default export and ability to import items individually, you can also export all functions individually:

// util.js

export function foo() { console.log('foo') }
export function bar() { console.log('bar') }
export function baz() { foo(); bar() }

export default {foo, bar, baz}

// a.js, using default export

import util from './util'
util.foo()

// b.js, using named exports

import {bar} from './util'
bar()

Or, as @loganfsmyth suggested, you can do without default export and just use import * as util from './util' to get all named exports in one object.

Answer from skozin on Stack Overflow
Top answer
1 of 4
227

The export default {...} construction is just a shortcut for something like this:

const funcs = {
    foo() { console.log('foo') }, 
    bar() { console.log('bar') },
    baz() { foo(); bar() }
}

export default funcs

It must become obvious now that there are no foo, bar or baz functions in the module's scope. But there is an object named funcs (though in reality it has no name) that contains these functions as its properties and which will become the module's default export.

So, to fix your code, re-write it without using the shortcut and refer to foo and bar as properties of funcs:

const funcs = {
    foo() { console.log('foo') }, 
    bar() { console.log('bar') },
    baz() { funcs.foo(); funcs.bar() } // here is the fix
}

export default funcs

Another option is to use this keyword to refer to funcs object without having to declare it explicitly, as @pawel has pointed out.

Yet another option (and the one which I generally prefer) is to declare these functions in the module scope. This allows to refer to them directly:

function foo() { console.log('foo') }
function bar() { console.log('bar') }
function baz() { foo(); bar() }

export default {foo, bar, baz}

And if you want the convenience of default export and ability to import items individually, you can also export all functions individually:

// util.js

export function foo() { console.log('foo') }
export function bar() { console.log('bar') }
export function baz() { foo(); bar() }

export default {foo, bar, baz}

// a.js, using default export

import util from './util'
util.foo()

// b.js, using named exports

import {bar} from './util'
bar()

Or, as @loganfsmyth suggested, you can do without default export and just use import * as util from './util' to get all named exports in one object.

2 of 4
31

One alternative is to change up your module. Generally if you are exporting an object with a bunch of functions on it, it's easier to export a bunch of named functions, e.g.

export function foo() { console.log('foo') }, 
export function bar() { console.log('bar') },
export function baz() { foo(); bar() }

In this case you are export all of the functions with names, so you could do

import * as fns from './foo';

to get an object with properties for each function instead of the import you'd use for your first example:

import fns from './foo';
Discussions

Nodejs - how group and export multiple functions in a separate file?
How can I group and export multiple functions in nodejs? I am trying to group all my util functions in utils.js: async function example1 () { return 'example 1' } async function example2 () ... More on stackoverflow.com
🌐 stackoverflow.com
How to export multiple functions ES6 - javascript
What I need to know: How can I export my sendData()? They used a short syntax so far because they only exported one function. How can I export multiple functions? More on stackoverflow.com
🌐 stackoverflow.com
Exporting multiple functions with module.exports in ES6
I'm building a node.js application and I'm trying to put all my mongodb logic in a seperate file. At this time this file only has one function to initialize the mongodb connection. I want to export... More on stackoverflow.com
🌐 stackoverflow.com
javascript - Exporting multiple functions with arguments
This complaints that there is no function getInstance. ... What is the proper way to export multiple functions like this? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Atomizedobjects
atomizedobjects.com › blog › javascript › how-to-export-multiple-functions-in-javascript
How to export multiple functions in JavaScript | Atomized Objects
August 27, 2021 - To export multiple functions in JavaScript, the easiest way to do so is by using the export statement before each function you want to export. As long as you do not export functions as default then you can export as many functions as you like from a module. All you have to do is apply the statement ...
🌐
YouTube
youtube.com › watch
Exporting Multiple JavaScript Functions from a Node Module - YouTube
We are going to build on our last tutorial and look at how you can export more than one item from a node module. This is done using an object.For more resour...
Published   January 30, 2019
🌐
LaunchCode
education.launchcode.org › intro-to-professional-web-dev › chapters › modules › exporting.html
13.4. Exporting Modules — Introduction to Professional Web Development in JavaScript documentation
The quick answer is, Yes. require only pulls in items identified in module.exports. The longer answer is, Hmmm, you missed the point. Just like functions, we want to keep modules small and specific. Each module should focus on a single idea and contain only a few related functions.
Find elsewhere
🌐
ProgrammingBasic
programmingbasic.com › home › javascript › javascript - how to export multiple functions from a file
JavaScript - How to export multiple functions from a file | ProgrammingBasic
However, if you are not using ES6 or a later version in your project, then you have to use the module.exports to export multiple functions from a file.
🌐
Codingem
codingem.com › home › how to export multiple functions in javascript
How to Export Multiple Functions in JavaScript - codingem.com
July 10, 2025 - To export multiple functions in JavaScript, call export by comma-separating the functions in curly braces. For example export { f1, f2, f3 }
🌐
GeeksforGeeks
geeksforgeeks.org › javascript › how-to-export-multiple-values-or-elements-in-a-module
How to export multiple values or elements in a Module ? - GeeksforGeeks
June 18, 2024 - export let element1 export const someValue export function foo(){...} Note: As we are exporting multiple values, while importing those values it is mandatory to use the same name of the corresponding object.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Statements › export
export - JavaScript - MDN Web Docs
July 29, 2025 - After the export keyword, you can use let, const, and var declarations, as well as function or class declarations. You can also use the export { name1, name2 } syntax to export a list of names declared elsewhere.
Top answer
1 of 1
1

Which one is a better approach to setting up variables in NodeJS? (faster, easier to maintain, not an antipattern)

Evaluating the merit of different options depends upon these factors:

  1. How many total options are there now?
  2. How likely are you to add more options as time goes?
  3. Does the caller always set all the options at once? Or is there value to being able to set just some options
  4. Does the caller usually just set one option?

Evaluating each of these:

Total number of options

First off, if you have lots of variables, then neither A or B are particularly practical. A is not very practical because you have to make a separate API for every variable when they're all really just doing the same thing, but for a slightly different property. That's generally not a good thing in an API design.

For lots of variables, option B ends up having to list out a lot of different values all in some precise order and that's not easy to use without having the doc page open every time you want to use it and it's not all that easy to read code that's written to use it either because the reader won't remember which position every single parameter is.

Extending to add more options in the future

Both A and B require modifying the API to extend and add more options. Option A requires adding and documenting a new API entry point. Option B requires adding and documenting a parameter and then making sure that prior code that doesn't include the new parameter isn't broken (by detecting the missing parameter on the receiving end of things). Neither is ideal.

Does the caller always set all options at once

If so, option A is a pain.

Does the caller usually set just one option or a small number of options

If so, option B is a pain.

Do, what you find is that neither option A or option B is entirely flexible for different types of calling usage or extensibility or use with lots of options.

Option C

So, I'll propose using a single options object to be a lot more flexible for different types of calling usage and infinite extensibility without changing the API surface itself. This is also trivial to maintain. Let's call this option C.

// default values for options
let defaultOptions = {
    optionA: defaultValA, 
    optionB: defaultValB, 
    optionC: defaultValC, 
    optionD: defaultValD, 
    optionE: defaultValE 
};

module.exports.setOptions = function(options) {
    // copy any properties from the options object to the default options
    //   overwriting default values with new values
    Object.assign(defaultOptions, options)
}

Or, in some cases, you want to prevent adding anything to defaultOptions that isn't already there (no additional properties allowed):

module.exports.setOptions = function(options) {
    // Copy any properties from the options object to the default options
    //   overwriting default values with new values
    // Only allow copying of properties that are already in defaultOptions
    for (let prop of Object.keys(options)) {
       if (Object.hasOwnProperty(defaultOptions, prop)) {
           defaultOptions[prop] = options[prop];
       }
    }
}

And, the caller would do something like this:

m.setOptions({
    optionC: "someNewValue",
    optionE: "anotherNewValue"
});

Where they can include only whatever options they want to set and they are named options so even if there were 1000 options and you just wanted to set 2 of them, it works quite cleanly.

For extensibility, option C wins every time because it can be extended by simply documenting that you now accept another property name without changing the surface of the API at all.


Option D

A fourth option which I will call option D, is to just have one "setter" function that takes a property name and a value.

// default values for options
let defaultOptions = {
    optionA: defaultValA, 
    optionB: defaultValB, 
    optionC: defaultValC, 
    optionD: defaultValD, 
    optionE: defaultValE 
};

module.exports.setProp = function(propName, value) {
    defaultOptions[propName] = value;
    return this;
}

This allows you to have one single function that could even be chainable that can set any property.

m.setProp("optionC", "someNewValue").setProp("optionE", "anotherNewValue");

This is probably better than option A if everything is just property name and value because it's more extensible without modifying the API, but it's a pain to use if you're trying to set a lot of properties (where option C excels).


Review

For option A, it's really only practical or best if you have a small number of options (say less than 5) and the caller is typically not setting multiple options (typically only setting one option). Even then, I probably still prefer option C as its infinitely extensible without adding more entry points to the API.


For option B, it's really only practical or best if you have a small number of options (say less than 5) and the caller is always setting all the options (or at most leaving off the last one or two). Option B is complicated to use and read if there are lots of options (because you have to remember the right position in the parameter list for each option) and it's complicated to overload to only pass some options. The best part of option B is that with a small number of options, it's probably the least typing for the caller, but that lesser typing means it's less self documenting than the object with named properties in option C.


For option C, it's infinitely extensible and flexible for any type of caller use from setting one property to setting hundreds of properties. And, it's trivial to maintain, even as you add more options. This is generally my preferred choice anytime I have 3 or more options or value extensibility or flexibility in how it's used by the caller.


For option D, I don't personally find it cleaner than option C, but it is flexible and extensible, though inefficient for setting a bunch of options.

🌐
Softwareshorts
softwareshorts.com › how-to-export-multiple-functions-in-javascript
How to export multiple functions in JavaScript | SoftwareShorts
You can use the export statement to export anything you like from a file, including strings, numbers, arrow functions, objects and arrays. 1export const add = (a, b) => a + b; 2 3export const multiply = (a, b) => a * b; 4 5export const divide = (a, b) => a / b; 6 7export const pi = "3.14" 8 ...
🌐
KnowledgeHut
knowledgehut.com › home › blog › web development › how to export node.js modules using exports
How to Export Node.js Modules Using Exports
September 13, 2023 - Use module.exports for exporting multiple items and use exports to export single items easily. ... Yes, they are similar in performance and result but different in syntax. Their items can be imported similarly as well.
🌐
CopyProgramming
copyprogramming.com › howto › how-to-export-multiple-functions-es6
Exporting Multiple ES6 Functions: A Rephrased Guide - Javascript
August 31, 2023 - Javascript - Exporting function in ES6 / react, There are a lot of ways to do such things: ES5 export module.export = instanceOfCollection then var getData = require ('my_module').getData ES6 … ... export multiple variables classes or functions at one time export more than one variable export ...
🌐
SitePoint
sitepoint.com › blog › javascript › understanding module.exports and exports in node.js
Understanding module.exports and exports in Node.js — SitePoint
January 29, 2024 - Then in the index.js file, we’re importing this function and executing it. Also notice that in the require statement, the module name is prefixed with ./, as it’s a local file. Also note that there’s no need to add the file extension. We can export multiple methods and values in the same way:
🌐
YouTube
youtube.com › watch
How to Export Multiple Functions with JavaScript Modules - YouTube
In today's video, I'll be taking you through how to export (or import) multiple functions using JavaScript modules. This is easily done and works both on the...
Published   March 14, 2023
🌐
Itsourcecode
itsourcecode.com › home › how to export multiple functions in javascript
How to Export Multiple Functions in JavaScript
August 18, 2023 - To export multiple functions using CommonJS, follow these steps: ... Organize your functions in particular files, each consisting of a specific set of related functions. ... In each file, use the module.exports objects to export the functions ...