# Introduction to CommonJS

> Learn how Node.js CommonJS modules use require and module.exports, how Node identifies them, and how they differ from ES modules.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-06-14 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/commonjs/

CommonJS is one of the two module systems supported by [Node.js](https://flaviocopes.com/nodejs/). It uses `require()` to load a module and `module.exports` to expose values.

The other system is [ES modules](https://flaviocopes.com/es-modules/), which uses `import` and `export`. New Node.js projects can use either system, and many npm packages publish one or both formats.

Modules are very cool, because they let you encapsulate all sorts of functionality, and expose this functionality to other JavaScript files, as libraries. They let you create clearly separate and reusable snippets of functionality, each testable on its own.

## How does Node.js identify a CommonJS module?

The clearest option is to use the `.cjs` file extension:

```js
// uppercase.cjs
function uppercase(string) {
  return string.toUpperCase()
}

module.exports = { uppercase }
```

For `.js` files, the nearest `package.json` controls the format:

```json
{
  "type": "commonjs"
}
```

Use `.mjs`, or `"type": "module"`, for ES modules. Being explicit avoids surprising differences between tools.

If a `.js` file has no controlling `type` field, current Node.js versions may inspect its syntax to choose a module system. Do not depend on that fallback in a package. Set `type` or use an explicit extension.

## How do you load a local module?

Use a relative path beginning with `./` or `../`:

```js
const { uppercase } = require('./uppercase.cjs')

console.log(uppercase('hello'))
```

Without `./`, Node treats the value as a built-in module or package name instead of a file next to the current module.

For example, this loads an installed package:

```js
const fastify = require('fastify')
```

Node's built-in modules can use the `node:` prefix:

```js
const fs = require('node:fs')
```

## How do exports work?

Every CommonJS module starts with a `module.exports` object. Add properties to it to export several values:

```js
function add(a, b) {
  return a + b
}

function subtract(a, b) {
  return a - b
}

module.exports = { add, subtract }
```

Then load them with [destructuring assignment](https://flaviocopes.com/es6/#destructuring-assignments):

```js
const { add, subtract } = require('./math.cjs')
```

To export one value, replace the entire object:

```js
function createServer() {
  // ...
}

module.exports = createServer
```

Then `require()` returns that function:

```js
const createServer = require('./create-server.cjs')
```

`exports` is only a shortcut pointing at `module.exports`. This works:

```js
exports.uppercase = uppercase
```

This does not export the function:

```js
exports = uppercase
```

Assign to `module.exports` whenever you replace the whole exported value.

## CommonJS modules are loaded synchronously

`require()` loads and evaluates a CommonJS module synchronously. Node caches the result after the first successful load, so later calls to the same resolved file normally receive the same exported object.

Each module has its own scope. Variables declared at the top level do not become global variables. Node also provides CommonJS-specific values such as `__filename`, `__dirname`, `module`, and `require`.

CommonJS was designed for server-side JavaScript. Browsers do not support `require()` directly, so browser code needs a bundler or should use native ES modules.

CommonJS and ES modules can interoperate, but the rules depend on the direction and on the Node.js version. If a package mixes formats, use explicit file extensions and follow the current [Node.js CommonJS documentation](https://nodejs.org/api/modules.html) and [package module rules](https://nodejs.org/api/packages.html).
