Node se envía con docenas de módulos que no necesitan ninguna npm install en absoluto: fs, http, path, crypto y más se compilan directamente en el binario node.
Colectivamente, esa es la biblioteca estándar de Node, y es lo suficientemente grande como para que un servicio de backend en funcionamiento a menudo pueda avanzar mucho antes de recurrir a su primera dependencia de terceros.
Conceptos básicos de las API incorporadas cubre los módulos de uso diario con código funcional; esta página es el mapa que está por encima de eso: qué distingue realmente un "incorporado" de un paquete npm, cómo Node organiza y estabiliza estas API a lo largo del tiempo, y por qué una parte creciente de ellas ahora reflejan las API de la plataforma web del navegador en lugar de inventar formas solo para Node.
Los módulos incorporados son código compilado directamente en el binario de Node y resuelto a través de un registro interno, no a través de una búsqueda de node_modules basada en disco, y la documentación de Node etiqueta cada uno con un nivel de Índice de Estabilidad que te dice qué tan seguro es depender de él.
Por qué es importante: Saber si una API es un módulo nativo de Node estable, una API de plataforma web adoptada o una adición experimental cambia la confianza con la que puedes construir sobre ella y cómo se comportará cuando actualices Node.
Conceptos clave:módulo incorporado, prefijo node:, Índice de Estabilidad, API nativa de Node, API de plataforma web, enlace interno.
Cuándo usar este modelo: Decidir si una necesidad ya está cubierta por Node antes de recurrir a npm, razonar si una API es segura para usar a largo plazo, depurar errores de TypeScript relacionados con tipos incorporados, y leer las páginas de fs, crypto, path, os/process, timers y util con el marco adecuado.
Limitaciones / Compensaciones: Los módulos incorporados se versionan con el propio tiempo de ejecución de Node, no de forma independiente; la actualización de Node puede cambiar el comportamiento de los módulos incorporados incluso cuando las dependencias de tu package.json no se han movido en absoluto.
Temas relacionados: resolución de módulos, especificadores de módulos node:, TypeScript en Node, el bucle de eventos.
Un módulo incorporado es código fuente que se envía compilado dentro del ejecutable node en lugar de como un archivo en disco que debe ser localizado y cargado.
Esa es la distinción central de cualquier cosa en npm: solicitar fs o crypto nunca toca la búsqueda de resolución de node_modules del sistema de archivos en absoluto; Node reconoce el nombre y devuelve la funcionalidad de su propio registro interno, al instante.
Node adoptó el prefijo explícito node: (import fs from 'node:fs') para eliminar cualquier ambigüedad entre un módulo incorporado y un paquete con el mismo nombre que alguien podría publicar teóricamente en npm.
El prefijo es opcional para la larga lista de módulos centrales originales por compatibilidad con versiones anteriores, pero es obligatorio para adiciones más recientes como node:test y node:sea, y es el patrón que la guía actual recomienda en todos los ámbitos porque hace que el origen de un módulo sea inequívoco a primera vista.
Una analogía útil: los módulos incorporados son como los servicios públicos de una ciudad: agua, energía, carreteras.
Siempre están presentes, estandarizados, y no los "instalas" como contratarías a un contratista privado (un paquete npm); simplemente vienen con vivir en la ciudad, y la propia ciudad (la versión de Node) decide cuándo y cómo cambian.
import { readFile } from 'node:fs/promises'; // Nativo de Node: API de la era de los callbacks, con promesasimport { randomUUID } from 'node:crypto'; // Nativo de Node: helpers criptográficos enfocados en el servidorconst res = await fetch('https://example.com'); // API de plataforma web: misma forma que en el navegador
Cada API de Node documentada lleva una calificación de Índice de Estabilidad que rige la cantidad de cambios que debes esperar: las API Experimentales pueden cambiar o desaparecer entre versiones menores, las API Estables solo se rompen en una versión principal de Node semver, y las API Heredadas se mantienen pero se desaconsejan activamente en favor de un reemplazo más nuevo.
Conceptos básicos de las API incorporadas cubre cómo leer realmente ese marcador en la documentación; el modelo mental aquí es lo que implica para tu código: una API Experimental en producción es un riesgo deliberado, no un descuido.
La mecánica de carga difiere fundamentalmente de los paquetes npm: un especificador incorporado se resuelve a través de una búsqueda de enlace interno integrada en el tiempo de ejecución, por lo que no hay E/S de disco, no hay resolución de campo principal de package.json y no hay dependencia de la configuración del sistema de módulos de tu proyecto más allá de si estás usando la sintaxis CJS o ESM en absoluto.
Esa es también la razón por la que los módulos incorporados se versionan con el propio binario de Node en lugar de forma independiente: una característica como util.parseEnv o el fetch global solo existe una vez que estás en una versión de Node que lo incluyó, independientemente de lo que esté fijado en package.json.
La biblioteca estándar se divide en dos familias distinguibles que se comportan de manera diferente en la práctica.
Las API nativas de Node —fs, http, net, cluster— fueron diseñadas específicamente para el mundo de Node impulsado por el servidor, los callbacks y EventEmitter, a menudo modeladas en llamadas al sistema POSIX, y no tienen equivalente en un navegador.
Las API de plataforma web adoptadas —fetch, URL, URLSearchParams, structuredClone, AbortController y crypto.webcrypto— son la implementación de Node de las mismas interfaces que exponen los navegadores, con una forma deliberadamente diseñada para que el mismo código pueda ejecutarse en Node, un navegador u otro tiempo de ejecución de JS como Deno o Bun sin un shim de compatibilidad.
Esa convergencia es un cambio estratégico real, no cosmético: las versiones anteriores de Node resolvían cada problema con una API específica de Node (http.get para llamadas de red), mientras que las versiones recientes prefieren cada vez más enviar el equivalente estándar web (fetch) junto con o en lugar de inventar algo nuevo.
El efecto práctico es que los paquetes isomorfos —bibliotecas destinadas a ejecutarse tanto en Node como en el navegador— pueden depender directamente de más de la plataforma, sin empaquetar un polyfill para cosas que Node ahora proporciona de forma nativa.
El propio proceso de deprecación de Node es una parte de primera clase de este modelo: las API deprecadas emiten advertencias en tiempo de ejecución (visibles a través de --pending-deprecation para las API que aún no advierten por defecto), lo que da a los equipos una ventana para migrar antes de que una API se elimine realmente en una futura versión principal.
Ese proceso es parte de lo que se supone que significa "Estable": incluso las API Estables pueden eventualmente ser deprecadas, pero solo a través de una ruta documentada y versionada en lugar de un cambio brusco silencioso.
El modelo de seguridad también difiere significativamente de las dependencias de npm.
Los módulos incorporados se envían a través del propio proceso de lanzamiento y asesoramiento de seguridad de Node, sin registro, sin nombre de paquete para typosquatting y sin árbol de dependencias transitivas para auditar, lo que es una razón real para preferir un módulo incorporado a un paquete npm equivalente cuando existe, más allá de simplemente evitar una instalación.
Eso no hace que los módulos incorporados estén libres de riesgos (el propio Node obtiene CVE, y el uso indebido de un módulo incorporado como child_process sigue siendo una clase de vulnerabilidad común); simplemente mueve el límite de confianza de "miles de mantenedores en un registro público" a "el equipo central de Node".
La observabilidad y el diagnóstico son un rincón infrautilizado de la biblioteca estándar que vale la pena mencionar aquí: módulos como node:perf_hooks, node:diagnostics_channel y node:async_hooks existen específicamente para instrumentar procesos de Node en producción sin agregar una dependencia de rastreo, y frameworks como Express y Fastify, junto con la mayoría de los ORM y controladores de bases de datos, se construyen directamente sobre node:http, node:net y node:tls.
TypeScript es un caso especial que vale la pena destacar: debido a que los módulos incorporados son enlaces C++ compilados expuestos como objetos JavaScript, no tienen información de tipo propia como lo tendría un archivo .ts escrito a mano.
El paquete @types/node es un conjunto de archivos de declaración escritos a mano y mantenidos por separado que describe la forma de cada módulo incorporado, por lo que es una devDependency en prácticamente todos los proyectos de TypeScript de Node, y por qué su versión debe seguir la versión de Node a la que realmente apuntas.
Fuente
Fortaleza
Debilidad
Mejor ajuste
Módulo incorporado nativo de Node (fs, http, crypto)
Sin instalación, sin riesgo en la cadena de suministro, versiones con el tiempo de ejecución
Forma de API específica de Node, a veces ergonomía de la era de los callbacks
E/S del lado del servidor, necesidades a nivel de SO y de proceso
API de plataforma web adoptada (fetch, URL)
Misma forma que el navegador, portable entre tiempos de ejecución
Las adiciones más nuevas pueden retrasarse en la paridad de características del navegador
Código isomorfo, clientes HTTP simples, manejo de URL
Paquete npm
Rellena huecos que los módulos incorporados no cubren, ecosistema de movimiento más rápido
Riesgo real en la cadena de suministro y mantenimiento, otra dependencia a auditar
Cualquier cosa genuinamente fuera del alcance de la biblioteca estándar
"Si no está en npm, tengo que escribirlo yo mismo." Una cantidad sorprendente de necesidades comunes ya están cubiertas por módulos incorporados: la generación de UUID, los clientes HTTP, el análisis de variables de entorno y el estilo de terminal se envían en Node moderno sin instalar nada.
"El prefijo node: es obligatorio para cada módulo central." Es opcional para los módulos establecidos desde hace mucho tiempo (fs, path, http) por compatibilidad con versiones anteriores, pero obligatorio para los más nuevos como node:test y node:sea.
"Los módulos incorporados nunca cambian ni se rompen." Cada módulo incorporado tiene un Índice de Estabilidad, y las API etiquetadas como Experimentales o Heredadas pueden cambiar o eliminarse en un plazo mucho más corto que "nunca".
"Las API de la plataforma web se comportan de forma idéntica en Node y en el navegador." La forma coincide deliberadamente, pero la semántica puede diferir: el fetch de Node no tiene aplicación de CORS y un comportamiento de agente/proxy predeterminado diferente al de un navegador.
"TypeScript entiende los módulos incorporados de Node de forma predeterminada." No lo hace: los módulos incorporados son enlaces compilados sin información de tipo inherente, que es exactamente lo que @types/node existe para proporcionar.
¿Qué hace que un módulo sea "incorporado" en lugar de algo que instalas?
Se compila directamente en el binario de Node y se resuelve a través de un registro interno en lugar de una búsqueda de node_modules en el disco: sin paso de instalación, sin recuperación de red, sin versión que fijar independientemente del propio Node.
¿Necesito el prefijo `node:` en cada importación de módulo central?
No, es opcional en módulos establecidos desde hace mucho tiempo como fs y path por compatibilidad con versiones anteriores, pero las adiciones más recientes (node:test, node:sea) lo requieren, y usarlo de manera consistente es la práctica recomendada actual de todos modos.
¿Qué me dice realmente el Índice de Estabilidad?
Te dice cuánto cambio esperar: las API experimentales pueden cambiar entre versiones menores de Node, las API estables solo se rompen en una actualización de versión principal, y las API heredadas se mantienen pero se desaconsejan activamente en favor de algo más nuevo.
¿Por qué Node tiene tanto `node:http` como el `fetch` global?
node:http es la primitiva de red original de Node, enfocada en el servidor; fetch es una adición posterior que refleja la API del navegador específicamente para que el mismo código cliente pueda ejecutarse sin modificaciones en Node, navegadores y otros tiempos de ejecución de JS.
¿Los módulos incorporados se versionan por separado de los paquetes en mi `package.json`?
No, las características y el comportamiento disponibles de un módulo incorporado están totalmente ligados a la versión de Node que estás ejecutando, por lo que actualizar Node puede cambiar lo que está disponible incluso si ninguna dependencia de package.json cambió en absoluto.
¿Por qué necesito `@types/node` si TypeScript ya entiende JavaScript?
Los módulos incorporados son enlaces C++ compilados expuestos como objetos JS simples, por lo que no tienen información de tipo incorporada como lo tendría el código fuente .ts escrito a mano; @types/node es un conjunto mantenido de archivos de declaración que describen sus formas.
¿Es más seguro usar un módulo incorporado que un paquete npm equivalente?
Generalmente sí, desde el punto de vista de la cadena de suministro: los módulos incorporados se envían a través del propio proceso de lanzamiento y seguridad de Node, sin registro, sin riesgo de typosquatting y sin árbol de dependencias transitivas para auditar, aunque los propios módulos incorporados aún pueden tener sus propios CVE.
¿El `fetch` global de Node se comporta exactamente igual que el de un navegador?
Coincide deliberadamente con la misma forma de API, pero el entorno de tiempo de ejecución difiere: el fetch del lado del servidor no tiene aplicación de CORS y una configuración de red predeterminada diferente (proxies, agentes) que un contexto de navegador.
¿Cómo me advierte Node antes de eliminar una API deprecada?
Las API deprecadas emiten advertencias de deprecación en tiempo de ejecución, y el indicador --pending-deprecation muestra advertencias para las API que aún no advierten por defecto, lo que da a los equipos una ventana documentada para migrar antes de una eventual eliminación.
¿Por qué los frameworks como Express se basan en `node:http` en lugar de reemplazarlo?
node:http ya maneja el ciclo de vida de solicitud/respuesta de bajo nivel y la gestión de sockets; los frameworks añaden enrutamiento, middleware y ergonomía en la parte superior en lugar de reimplementar las primitivas de red que Node ya proporciona.
¿Cuál es un ejemplo de una necesidad específica de Node sin equivalente en la plataforma web?
Las preocupaciones a nivel de proceso y sistema operativo, como la creación de procesos hijos, la bifurcación para múltiples núcleos de CPU, la lectura de la memoria del host y la información de la CPU, no tienen un análogo en el navegador, ya que los navegadores no tienen el concepto de un proceso del sistema operativo para exponer.