Skip to navigation Skip to main content
Eleventy
Eleventy Documentation
Stable
3.0.0
Toggle Menu
Eleventy 5.81s
Remix 40.14s

CommonJS vs. ESM

Contents

Historically, Eleventy (prior to version 3) has worked with the Node.js default flavor of JavaScript modules: CommonJS. Practically speaking, this means you used module.exports and require() in any .js (or .cjs) files in your project. This affected Configuration files, JavaScript Data Files, and JavaScript (.11ty.js) templates.

However, ESM (ECMAScript Modules) are a newer JavaScript standard that will work in more JavaScript environments and runtimes. Instead of module.exports and require(), you’ll use export and import().

Runtimes

Node.js

If you want to start using ESM in your project, there are two ways to do it in Node.js (both of which work fine in Eleventy v3):

  1. Project-wide: Adding "type": "module" in your package.json, which swaps the default for .js files from CommonJS to ESM.
  2. Individual files (incremental migration): by using the .mjs file extension instead of .js you can change a single file to use ESM.

You can also choose to keep using CommonJS in your Eleventy project: using ESM is not required. Eleventy will continue to support CommonJS moving forward. Our documentation shows both CommonJS and ESM versions of each JavaScript code snippet.

.js, .cjs, and .mjs file extensions are supported for Configuration Files, JavaScript Data Files and JavaScript (.11ty.js) templates.

Configuration

Read more about supported configuration file names.

CommonJS Configuration

If you use Eleventy bundled plugins (e.g. I18nPlugin, RenderPlugin, or HTMLBasePlugin, among others), you will not be able to require Eleventy directly in your configuration file.

Consider this CommonJS configuration file:

// Any combination of these
const { I18nPlugin, RenderPlugin, HtmlBasePlugin } = require("@11ty/eleventy");

module.exports = function (eleventyConfig) {
// …
};

In Eleventy v3 you’ll need to use a dynamic import() instead of require (or change your configuration file to use ESM):

module.exports = async function (eleventyConfig) {
const { I18nPlugin, RenderPlugin, HtmlBasePlugin } = await import("@11ty/eleventy");
// …
};

Note the async configuration callback. This change is to work around limitations in Node.js with require("ARBITRARY_ESM_PACKAGE"). Future versions of Node.js may fix this limitation.

If you attempt to require("@11ty/eleventy") with Eleventy v3, we’ll throw a very helpful error message which will provide you exact instructions on how to fix the issue.

ESM Configuration

Your configuration file using ESM will look like this:

// Any combination of these
import { I18nPlugin, RenderPlugin, HtmlBasePlugin } from "@11ty/eleventy";

export default function (eleventyConfig) {
// …
};

Note the use of import and export default.

Plugins

You can write your Eleventy plugins in CommonJS or ESM too.

  • If you write them in ESM you’ll have to instruct folks to use the same approach as above (using dynamic import()).
  • CommonJS plugins will work without additional instruction needed (you can import a CommonJS package directly without incident).

Other pages in Learn: