Skip to content
NewBun 1.4.5 is out. Release notes
AphrodyBun

Linter · Rules

import/no-commonjs

Disallow require(), module.exports and exports.* in favor of import and export

In a project that uses ES modules, a require() or module.exports written out of habit mixes two module systems. Bundlers can't tree-shake anything that's loaded with require(), and the other import/* rules can't check names that are exported through module.exports.

A require() is reported if it has one string as its argument and isn't inside a function. By default it's also allowed inside an if, a try, a ? : or an &&, || or ??, because an import declaration can't be conditional.

Configure

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"import/no-commonjs" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"import/no-commonjs" = ["error", {
  allowRequire = false,
  allowConditionalRequire = true,
  allowPrimitiveModules = false,
}]

Examples

Reported:

const { parse } = require("./parse");

module.exports = { run: text => parse(text) };
import { parse } from "./parse";

exports.run = text => parse(text);

Not reported:

import { parse } from "./parse";

export const run = text => parse(text);

let colors;
try {
  colors = require("colors");
} catch {}

export function loadMarkdown() {
  return require("markdown-it");
}

Options

OptionDefaultWhat it does
allowRequirefalseAllow every require(). module.exports and exports.* are still reported.
allowConditionalRequiretruefalse also reports a require() inside an if, a try, a ? : or a logical expression.
allowPrimitiveModulesfalseAllow module.exports = value if the value isn't an object literal.

The string "allow-primitive-modules" instead of the object means { "allowPrimitiveModules": true }.

const { parse } = require("./parse");

export const run = text => parse(text);
let colors;
try {
  colors = require("colors");
} catch {}

export { colors };

With allowPrimitiveModules, a module may export one function or one string:

module.exports = function run(text) {
  return text.trim();
};
module.exports = { run };

When not to use it

Leave it off in a project that's written in CommonJS, and for config files that a tool loads with require().