Configuring Module Format

Modern SDKs need to balance compatibility with performance. The moduleFormat option in the SDK generator allows developers to control whether an SDK is built for CommonJS (CJS), ECMAScript Modules (ESM), or both. This choice impacts bundle size, tree-shaking performance, and compatibility with Node.js and modern bundlers.

How to Configure Module Format

To configure the module format, update gen.yaml (which is often located in the SDK’s .speakeasy directory) file under the typescript section:

# .speakeasy/gen.yaml
typescript:
# add or modify `moduleFormat`
moduleFormat: "commonjs" # or "esm" or "dual"
# other Typescript configuration options...

Supported Options

  • "commonjs" (default): Builds SDK for CommonJS. Widely supported but less optimized for tree-shaking.
  • "esm": Builds SDK for ECMAScript Modules. Optimal tree-shaking, smaller bundles, but limited compatibility.
  • "dual": Builds SDK for both CJS and ESM. Flexible, with slight build time increase.

Module Format Overview

moduleFormat determines the module system targeted during SDK build. It impacts:

  • Node.js project compatibility,
  • Bundler tree-shaking capabilities,
  • SDK bundle size, and
  • Build performance.

Example Outputs for Each Option

CommonJS (Default)

When configured with commonjs:

// CommonJS import in consumer code
const { ApiError } = require("petstore/errors/apierror.js");
// ESM import (interop code included)
import { ApiError } from "petstore/errors/apierror.js";

ESM

When configured with esm:

// Native ESM import in consumer code
import { ApiError } from "petstore/errors/apierror.js";
// ❌ Will not work in CommonJS-only environments

Dual

When configured with dual:

// ESM import (no interop code)
import { ApiError } from "petstore/errors/apierror.js";
// CommonJS import (still works seamlessly)
const { ApiError } = require("petstore/errors/apierror.js");

How to Decide Which Format to Use

Use CommonJS (commonjs) if…

  • The SDK is used primarily for Node.js and older projects.
  • Bundle size is not a priority.

Use ESM (esm) if…

  • SDK consumers use modern bundlers like Vite or Webpack.
  • Tree-shaking and bundle size are top priorities.

Use Dual Mode (dual) if…

  • Compatibility with both Node.js and modern bundlers is important.
  • Build time is not critical.

Additional Reading