29

I'm looking for a way to find out if a module is available.

For example, I want to check if the module mongodb is available, programmatically.

Also, it shouldn't halt the program if a module isn't found, I want to handle this myself.

PS: I added this question because Google isn't helpful.

0

6 Answers 6

31

Before you upvote: Thanks! But really, go upvote this answer by Jakob hanging at the bottom of this page right now, because in 2025 (and for years now really) this is no longer the best answer. Jakob's is. It is in fact the ONLY answer that is still relevant today, unless you are stuck with require for some reason. Javascript has native modules now and Node JS and the browsers and basically everything supports them. Use it!

-------

DEPRECATED

There is a more clever way if you only want to check whether a module is available (but not load it if it's not):

function moduleAvailable(name) {
    try {
        require.resolve(name);
        return true;
    } catch(e){}
    return false;
}

if (moduleAvailable('mongodb')) {
    // yeah we've got it!
}
Sign up to request clarification or add additional context in comments.

Comments

17

Here is the most clever way I found to do this. If anyone has a better way to do so, please point it out.

var mongodb;
try {
    mongodb = require( 'mongodb' );
}
catch( e ) {
    if ( e.code === 'MODULE_NOT_FOUND' ) {
        // The module hasn't been found
    }
}

2 Comments

Be careful using this with your own modules. MODULE_NOT_FOUND will be called if a nested require fails. To avoid this a regex could be used on the message to check which module was not found. It would be advisable to print the actual error message to the console. Using require.resolve first would avoid this too.
Wouldn't this be better if it were to rethrow the error if it isn't MODULE_NOT_FOUND?
2

For ECMAScript modules (ESM) since Node 12 the import keyword can also be used as function that returns a Promise:

import("mongodb")
  .then(mongodb => {
    // use module
  })
  .catch(e => console.error(e)) // The module hasn't been found

or

async main() {
  const mongodb = import("mongodb")
  // use module
}

main().catch(e => console.error(e)) // module hasn't been found or other error

Comments

0

Maybe resolve-like modules will be helpfully here?

The numbers of modules are exist on npm:

I wrote first, async-resolve, and for example:

var Resolver = require('async-resolve');
var resolver_obj = new Resolver();
resolver_obj.resolve('module', __dirname, function(err, filename) {
  return console.log(filename);
});

It use node modules path resolutions rules but don't block main loop as node do it. And in result you get filename, so it can be used to decide its local module or global and other things.

Comments

0

ES6 simple solution with 1 line of code :

const path = require('path');
const fs = require('fs');

function hasDependency(dep) {
        return module.paths.some(modulesPath => fs.existsSync(path.join(modulesPath, dep)));
}

1 Comment

Please explain your answer with some code comments or some descriptive text in the answer. A lot of skill levels will find this and it can be easier to sue if it is explained.
-9

using ES6 arrow functions

var modulePath = m => { try { return require.resolve(m) } catch(e) { return false } }

5 Comments

What's the advantage of using ES6 arrow functions? Is it worth answering a 3 years old question for this?
@Florian Margaine the advantage of arrow functions is that all work can be done in one line
that's not an advantage when you have a try/catch on a single line. Never do that. Seriously.
@Florian Margaine what about now?
then there is no advantage to using arrow function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.