CommonJS, ESM, and TypeScript
On this page
- Related: JavaScript Modules on MDN
Eleventy works with many different flavors of JavaScript:
- CommonJS: the original flavor of Node.js, for broadest compatibility with older versions of Node.js.
- ECMAScript Modules (ESM) (recommended): the new JavaScript standard for future-friendly code. This is most compatible with alternative JavaScript environments and runtimes (browsers, even!).
- TypeScript: adds types to JavaScript. Typically requires transpilation but natively supported in Node.js (via type stripping in Node 22.6+) and Deno.
Compatibility
Eleventy is compatible with ESM, CommonJS, and TypeScript (with some runtime limitations). Note the following:
| Feature | CommonJS | ESM | TypeScript (CommonJS) | TypeScript (ESM) |
|---|---|---|---|---|
@11ty/eleventy Compatibility | v0+ | v3+ | v3+ (additional configuration required) | v3+ (additional configuration required) |
.js files use (unless package.json→type) | ✅ .js in Node.js | ✅ .js in Deno | - | - |
.ts files use (unless package.json→type) | - | - | ✅ .ts in Node.js | ✅ .ts in Deno |
| Explicit File Extension | .cjs | .mjs | .cts | .mts |
| Node.js Compatibility | Node.js * | Node.js v12.20+ | Node.js v22.6+ | Node.js v22.6+ |
| Deno Compatibility | Deno v2+ | Deno * | Deno v2+ | Deno * |
You can mix and match different flavors when using the following Eleventy project files and features:
- Configuration files
- JavaScript Data Files
- JavaScript Templates (e.g.
11ty.js) - JavaScript Front Matter
JavaScript Runtimes
Eleventy has goals to broadly support the same module formats as your chosen JavaScript runtime.
Node.js and Deno
CommonJS, ESM, and TypeScript are supported in Node.js and Deno.
If you want to use ESM (in JavaScript or TypeScript) in your Eleventy (v3+) project, you can do this project-wide or incrementally on a per-file basis:
- Project-wide: Adding
"type": "module"in yourpackage.json, which specifies that.js(and.ts) files use ESM (this is the default in Deno, swap back to CommonJS using"type": "commonjs"). When using ESM, use.cjs(or.cts) file extensions to mark individual files as CommonJS. - Individual files (incremental migration): by using the
.mjs(and.mts) file extension instead of.jsyou can change a single file to use ESM.
If your Eleventy project already uses CommonJS, you can keep using CommonJS: using ESM is not required. Eleventy will continue to support CommonJS moving forward. Our docs include code snippets for both CommonJS and ESM.
.js, .cjs, and .mjs file extensions are supported for Configuration Files, JavaScript Data Files and JavaScript (.11ty.js) templates. With additional configuration, you can use .ts, .cts, and .mts file extensions for TypeScript for these features as well.
- Related: read more about Deno’s CommonJS compatibility.
Configuration
Read more about supported configuration file names.
ESM Configuration
Your configuration file using ESM can use Eleventy bundled plugins (like i18n, Render, InputPath to URL, id Attribute or HTML <base>) directly:
// Any combination of these import { I18nPlugin, RenderPlugin, HtmlBasePlugin } from "@11ty/eleventy"; export default function (eleventyConfig) { // … }; Note the use of import and export default.
CommonJS Configuration
If you use Eleventy bundled plugins (like i18n, Render, InputPath to URL, id Attribute or HTML <base>), you have a few options to use Eleventy v3 in your configuration file.
Consider this CommonJS configuration file:
// This requires Node v20.19 or newer const { I18nPlugin, RenderPlugin, HtmlBasePlugin } = require("@11ty/eleventy"); module.exports = function (eleventyConfig) { // … }; - Read more about
require(ESM)in Node.js
If you attempt to require("@11ty/eleventy") with Eleventy v3 in a version of Node that does not support it, we’ll throw a very helpful error message which will provide you exact instructions on how to fix the issue.
CommonJS Configuration in Node 18
For older versions of Node.js, 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.
Using ESM plugins in CommonJS Configuration
You can use any third-party plugin written in ESM using the same approach. Keep in mind that using default export as the plugin callback, you will need to use the special default property supplied from dynamic import().
module.exports = async function (eleventyConfig) { const { default: myPlugin } = await import("my-eleventy-plugin"); // … }; Plugins
You can write your Eleventy plugins in CommonJS or ESM too. Which should you choose?
| Feature | ESM or CommonJS |
|---|---|
| Compatibility with Eleventy v3 and newer | ✅ ESM |
| Compatibility with Eleventy v2 or older | ✅ CommonJS |
| Compatibility with Node 20.19+ | ✅ ESM |
| Compatibility with older Node < 20.19 | ✅ CommonJS |
Notably, the same limitations documented above for Eleventy bundled plugins will apply to your plugin code as well!