Skip to navigation Skip to main content
These docs are for an upcoming version of Build Awesome — take extra care before linking here as URLs may change! Look to the latest stable docs instead (or the full release history).

CommonJS, ESM, and TypeScript

On this page

Build Awesome works with many different flavors of JavaScript:

  • CommonJS: the original flavor supported in Node.js, use if you need the broadest compatibility with older versions of Node or Build Awesome (or Eleventy).
  • ECMAScript Modules (ESM) (recommended): the new JavaScript standard for future-friendly code. This is most compatible with alternative JavaScript environments and runtimes (even web browsers).
  • TypeScript: adds types to JavaScript. Natively supported in Node.js (via type stripping in 22.6+) and Deno.

Compatibility

Build Awesome is compatible with ESM, CommonJS, and TypeScript (with some runtime limitations). Note that Node defaults to CommonJS and Deno defaults to ESM:

Feature CommonJS ESM TypeScript (CommonJS) TypeScript (ESM)
Node.js defaults .js .cjs .mjs .ts .cts .mts
Deno defaults .cjs .js .mjs .cts .ts .mts

You can override the default flavor for .js and .ts files using a type property in your package.json file.

You can mix and match different flavors when using the following project files and features:

JavaScript Runtimes

Build Awesome 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 project, you can do this project-wide or incrementally on a per-file basis:

  1. Project-wide: Adding "type": "module" in your package.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.
  2. Individual files (incremental migration): by using the .mjs (and .mts) file extension instead of .js you can change a single file to use ESM.

If your Build Awesome or Eleventy project already uses CommonJS, you can keep using CommonJS: using ESM is not required. We 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.

Configuration

Read more about supported configuration file names.

ESM Configuration

Your configuration file using ESM can use core bundled plugins (like i18n, Render, InputPath to URL, id Attribute or HTML <base>) directly:

// Any combination of these
import { I18nPlugin, RenderPlugin, HtmlBasePlugin } from "@awesome.me/buildawesome";

export default function ($config) {
	// …
};

Note the use of import and export default.

CommonJS Configuration

If you use core bundled plugins (like i18n, Render, InputPath to URL, id Attribute or HTML <base>), you have a few options in your configuration file.

Consider this CommonJS configuration file:

// This requires Node v20.19 or newer
const { I18nPlugin, RenderPlugin, HtmlBasePlugin } = require("@awesome.me/buildawesome");

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

If you attempt to require("@awesome.me/buildawesome") with Build Awesome (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 ($config) {
	const { I18nPlugin, RenderPlugin, HtmlBasePlugin } = await import("@awesome.me/buildawesome");
	// …
};

Note the async configuration callback.

Using ESM plugins in CommonJS Configuration

Remember, you can use require to import an ESM plugin in Node 20.19 and newer (and ignore this section).

But if you’re on an older version of Node, you can use ESM plugins in a CommonJS configuration file with dynamic import. 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 ($config) {
	const { default: myPlugin } = await import("my-plugin");
	// …
};

Plugins

You can write your plugins in CommonJS or ESM too. Which should you choose?

Feature ESM or CommonJS
Okay with Build Awesome 4+, Eleventy 3+ and Node 20.19+ compatibility? Use ESM
Need compatibility with older versions of Eleventy (≤ 2) or Node (≤ 20.18)? Use CommonJS

It is not recommended to use TypeScript in plugin code as type stripping is not supported in Node.js’ node_modules folder.

Notably, the same limitations documented above for Build Awesome bundled plugins will apply to your plugin code as well!


Other pages in Learn