Diferencias entre distintos tipos de módulos en JavaScript

CommonJS, AMD, UMD y ESM son diferentes sistemas de módulos en JavaScript.

tipos-modulos-javascript-commonjs-amd-umd-esm

Los módulos permiten dividir el código en piezas reutilizables y mantener una estructura organizada. En JavaScript, existen varios sistemas de módulos que han ido apareciendo a lo largo del tiempo, impulsados por necesidades específicas del entorno (navegador, servidor, compatibilidad, etc.). Comprender las diferencias entre CommonJS (CJS), AMD, UMD y ECMAScript Modules (ESM) nos ayuda a elegir el formato adecuado según el contexto en el que trabajamos.

AMD (Asynchronous Module Definition)

AMD fue creado para navegadores, donde la carga asíncrona de scripts es necesaria para no bloquear la ejecución.

Características principales:

  • Carga asíncrona
  • Usa define y require
  • Diseñado para navegadores

Ejemplo:

math.js
define([], function () {
return {
sumar: function (a, b) {
return a + b;
}
};
});
// app.js
require(['math'], function (math) {
console.log(math.sumar(2, 3)); // 5
});

AMD fue común en aplicaciones web antes de que existieran herramientas modernas de bundling. Actualmente, su uso es menos frecuente, aunque sigue presente en proyectos que dependen de RequireJS.

CommonJS (CJS)

CommonJS fue diseñado para aplicaciones del lado del servidor, principalmente en Node.js. Su objetivo es permitir cargar módulos de forma síncrona.

Características principales:

  • Carga síncrona (require)
  • Exportación con module.exports o exports
  • Específico de Node.js (no compatible en navegadores sin herramientas adicionales)

Ejemplo:

math.js
function sumar(a, b) {
return a + b;
}
module.exports = { sumar };
// app.js
const math = require('./math');
console.log(math.sumar(2, 3)); // 5

Para entornos donde no se necesita carga dinámica o ejecución en el navegador, CJS sigue siendo útil.

UMD (Universal Module Definition)

UMD intenta ser compatible con CJS, AMD y también con entornos sin sistema de módulos. Fue útil para distribuir librerías que funcionaran en cualquier contexto.

Características principales:

  • Detecta el entorno y adapta la exportación/importación
  • Compatible con CJS, AMD y globales del navegador

Ejemplo:

(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.math = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
return {
sumar: function (a, b) {
return a + b;
}
};
}));

El código anterior permite que una misma librería funcione con RequireJS, Node.js o directamente en el navegador como variable global.

ECMAScript Modules (ESM)

ESM es el sistema oficial de módulos definido en el estándar de JavaScript. Está soportado de forma nativa en navegadores modernos y en Node.js (desde la versión 12 con ciertas condiciones).

Características principales:

  • Sintaxis declarativa (import / export)
  • Carga asíncrona por defecto en el navegador
  • Permite tree-shaking (eliminar código muerto que no se usa)

Ejemplo:

math.js
export function sumar(a, b) {
return a + b;
}
// app.js
import { sumar } from './math.js';
console.log(sumar(2, 3)); // 5

ESM es hoy la opción preferida para nuevos proyectos. Mejora la claridad del código, permite mejores optimizaciones durante el bundling y tiene soporte nativo sin necesidad de herramientas adicionales.

Tabla comparativa

SistemaCargaEntorno principalSintaxisComentarios
CJSSíncronaNode.jsrequire, exportsSimple, no apto para navegadores
AMDAsíncronaNavegadordefine, requireUso en desuso, dependiente de RequireJS
UMDDetecta todoHíbridoFunción envolventeÚtil para librerías universales
ESMAsíncronaNavegador y Nodeimport, exportRecomendado para nuevos proyectos

Conclusión

Cada sistema de módulos responde a necesidades técnicas y de compatibilidad concretas. CommonJS resolvió los requerimientos de modularidad en Node.js. AMD lo hizo para el navegador. UMD sirvió como puente entre ambos. Finalmente, ESM unifica criterios bajo el estándar oficial del lenguaje.

Al elegir uno u otro, el entorno de ejecución y el objetivo del proyecto definen el camino. Para aplicaciones actuales, especialmente aquellas que serán compiladas con herramientas como Vite, Webpack o Rollup, lo más conveniente suele ser optar por ESM. Aun así, conocer los demás sistemas permite comprender mejor muchas bases de código existentes.