Qué es Node.js en realidad
Node.js es un programa que instalas en tu equipo y que se encarga de ejecutar archivos JavaScript. Esa es la descripción más sencilla, y es totalmente cierta. Cuando escribes node script.js, Node lee el archivo, se lo entrega al motor V8 de Google (el mismo motor de JavaScript que usa Chrome) y lo ejecuta — con una buena cantidad de APIs adicionales encima para cubrir todo lo que V8 por sí solo no puede hacer.
V8 sabe ejecutar JavaScript. Lo que no sabe es abrir un archivo, escuchar en un socket TCP, lanzar un proceso o leer una variable de entorno. De todo eso se ocupa Node: lo implementa en C++ y lo expone a tu código JavaScript como módulos integrados.
node --version
node script.js
Node no es un lenguaje. Tampoco es un framework. Es un runtime: V8 más una librería estándar más un sistema de módulos más un event loop. Y ya está, eso es todo.
Tu primer script en Node
Cualquier archivo .js es un programa de Node válido. Sin boilerplate, sin función main:
console.log funciona igual que en el navegador. Los template literals, Date, los arrays, las promesas… todo lo que ya conoces del lenguaje viene del motor V8 y se comporta exactamente igual. Lo que cambia en Node es lo que tienes a tu alrededor.
Globales que solo existen en Node
El navegador te da window, document, localStorage o fetch. Node, en cambio, trae otro conjunto de globales pensados para un runtime del lado del servidor:
processrepresenta el proceso de Node en ejecución. Contiene las variables de entorno (process.env), los argumentos de línea de comandos (process.argv) y métodos para terminar el proceso (process.exit(1)).__filenamey__dirnamete devuelven la ruta absoluta del archivo actual y de su carpeta. (Ojo: en módulos ES no existen; ahí se usaimport.meta.url.)globales el objeto global, el equivalente en Node alwindowdel navegador.
Aquí no hay document ni window. Si intentas usarlos, te saltará un ReferenceError. Suele ser la primera pista de que una librería fue pensada para el navegador y no va a funcionar en Node tal cual.
Argumentos de línea de comandos y variables de entorno
Buena parte de lo que se hace con Node —CLIs, scripts de build, servidores— pasa por leer argumentos y variables de entorno. Ambos viven dentro de process:
process.argv es un array: las dos primeras posiciones corresponden a la ruta del binario de Node y a la ruta del script, así que tus argumentos reales empiezan en el índice 2. Por su parte, process.env es un objeto plano con las variables de entorno — leer de ahí NODE_ENV, PORT o claves de API es algo habitual.
Módulos integrados de Node
Node trae una biblioteca estándar a la que accedes mediante require (CommonJS) o import (ESM). Los nombres de los módulos llevan el prefijo node: para dejar claro que son parte del núcleo:
Los que más vas a usar:
node:fs— leer y escribir archivos. Usanode:fs/promisessi prefieres la versión con async/await.node:path— unir, resolver y parsear rutas de archivos de forma multiplataforma.node:http/node:https— montar servidores HTTP y hacer peticiones.node:url— parsear y construir URLs.node:os— información sobre la máquina anfitriona.node:crypto— hashing, bytes aleatorios, cifrado.
Estos no se instalan: vienen de serie con Node. Todo lo demás sale de npm.
El event loop de Node, en pocas palabras
Node ejecuta tu JavaScript en un solo hilo, pero es capaz de atender muchas cosas a la vez. Ese es justo el truco del event loop. Cuando llamas a algo asíncrono —una lectura de archivo, una petición HTTP, un temporizador— Node delega el trabajo real al sistema operativo (o a su pool de hilos) y sigue ejecutando código. Al terminar esa tarea, se encola un callback, y el loop lo recoge en cuanto el código actual acaba.
El orden que se imprime es 1, 4, 2, 3. Primero corre el código síncrono. Luego las microtareas (promesas resueltas). Y al final, los timers. Por eso un bucle pesado que consume CPU bloquea todo el servidor: solo hay un hilo para tu código. La concurrencia de Node va de I/O, no de cálculo.
Un servidor HTTP mínimo
La recompensa de todo esto es que un servidor web funcional cabe en unas pocas líneas:
Sin frameworks, sin dependencias. createServer recibe una función que se ejecuta en cada petición, y listen arranca el event loop para procesar las conexiones entrantes. En aplicaciones reales se usa Express o Fastify por encima de esto, pero por debajo sigue siendo el mismo módulo integrado http.
Node js vs navegador: diferencias clave
Conviene dejar claro qué se comparte y qué no:
| Funciona en ambos | Solo en Node | Solo en el navegador |
|---|---|---|
Características del lenguaje (clases, promesas, async/await) | fs, http, process, __dirname | window, document, DOM |
console.log | CommonJS require / particularidades de ESM en Node | localStorage, sessionStorage |
fetch (Node 18+) | Acceso al sistema de archivos y a sockets de red | Eventos de usuario, renderizado |
setTimeout, setInterval | Procesos hijos, streams | History API, navigator |
Las versiones modernas de Node han ido incorporando varias APIs del navegador —fetch, URL, AbortController, structuredClone—, así que la distancia es menor que antes. Aun así, el DOM no va a llegar a Node, ni el sistema de archivos al navegador.
Node vs Deno vs Bun
Node sigue siendo la opción por defecto, pero ya no es el único runtime de JavaScript. Deno y Bun son alternativas: Deno viene del creador original de Node, y Bun es obra de un equipo más reciente centrado en la velocidad. Ambos ejecutan JavaScript (y TypeScript de forma nativa), incluyen herramientas integradas como test runner y bundler, y se diferencian de Node en cómo gestionan los módulos, los permisos y la instalación de paquetes.
Si estás aprendiendo JavaScript, Node es donde vas a encontrar la documentación, los tutoriales y las ofertas de trabajo. Los conceptos —event loop, módulos, APIs integradas— se trasladan casi por completo a los otros runtimes. Aprende Node primero y pásate a los demás cuando un proyecto concreto lo pida.
Ejecutar scripts de forma rápida
Algunas formas prácticas de lanzar código mientras trabajas:
# Run a file
node script.js
# Run a one-liner
node -e "console.log(2 ** 10)"
# Open the REPL (interactive prompt)
node
# Watch a file and re-run on save (Node 18.11+)
node --watch script.js
El REPL viene genial como bloc de notas cuando quieres comprobar qué devuelve un método sin tener que crear un archivo. La opción --watch es muy útil mientras desarrollas: guardas el archivo y Node vuelve a ejecutar el script automáticamente.
Lo que viene: manejo de errores
Una cosa es que el código se ejecute y otra muy distinta es saber qué hacer cuando algo falla. Las lecturas de archivos fallan, las peticiones HTTP se quedan sin tiempo, el parseo de JSON lanza excepciones. El próximo capítulo va sobre try/catch, los tipos de errores y los patrones para lidiar con todo lo que se rompe, que en un programa Node, tarde o temprano, acaba siendo todo.
Preguntas frecuentes
¿Qué es el runtime de Node.js?
Node.js es un programa que ejecuta JavaScript fuera del navegador. Combina el motor V8 de Google (el mismo que corre JS en Chrome) con una capa en C++ que aporta APIs que V8 por sí solo no tiene: acceso al sistema de archivos, red, procesos, temporizadores... Esa mezcla es la que te permite crear servidores, CLIs y herramientas de build con JavaScript.
¿En qué se diferencia Node del navegador?
Los dos ejecutan JavaScript, pero las APIs que rodean al lenguaje no son las mismas. El navegador te da window, document y el DOM. Node te da process, fs, http, __dirname y carga de módulos con CommonJS/ESM. En Node no hay DOM y en el navegador no hay sistema de archivos: el lenguaje es el mismo, la plataforma no.
¿Node.js es un framework o un runtime?
Es un runtime. Node por sí mismo no te impone ninguna estructura de aplicación: simplemente ejecuta JavaScript y expone APIs. Frameworks como Express, Next.js o NestJS se construyen encima de Node. Deno y Bun son runtimes alternativos de JavaScript que compiten con Node, pero cumplen el mismo papel.
¿Qué es el event loop en Node?
El event loop es lo que le permite a Node gestionar muchas cosas a la vez usando un único hilo. Cuando llamas a algo asíncrono —una lectura de fichero, una petición HTTP, un setTimeout— Node delega el trabajo al sistema y sigue ejecutando código. Cuando ese trabajo termina, su callback entra en cola y el event loop lo recoge. Por eso fs.readFile no bloquea al resto del programa.