Introducción a Express

Intermedio
Node
Node
Actualizado: 03/09/2025

¿Qué es Express y por qué usarlo con Node?

Express.js es un framework web minimalista y flexible para Node.js que simplifica significativamente la creación de aplicaciones web y APIs. Lanzado en 2010, se ha convertido en el framework de referencia del ecosistema Node.js, siendo utilizado por millones de desarrolladores en todo el mundo.

Mientras que Node.js proporciona el entorno de ejecución para JavaScript en el servidor, Express actúa como una capa de abstracción que facilita el desarrollo de aplicaciones web robustas. Si pensamos en Node.js como el motor de un coche, Express sería como el chasis y los controles que hacen que conducir sea una experiencia práctica y segura.

¿Qué hace especial a Express?

Express se define como un framework "sin opiniones" (unopinionated), lo que significa que no impone una estructura rígida sobre cómo debes organizar tu código. Esta filosofía te permite estructurar tu aplicación según las necesidades específicas de tu proyecto.

El framework sigue una arquitectura basada en middleware, donde cada pieza de funcionalidad se puede agregar como un componente modular. Esto permite que las peticiones HTTP pasen por una serie de funciones que pueden modificar la solicitud, la respuesta, o ambas.

const express = require('express');
const app = express();

// Middleware básico que se ejecuta en todas las peticiones
app.use((req, res, next) => {
  console.log(`${req.method} ${req.path} - ${new Date().toISOString()}`);
  next(); // Pasa el control al siguiente middleware
});

// Ruta básica
app.get('/', (req, res) => {
  res.send('¡Hola desde Express!');
});

¿Por qué usar Express con Node.js?

Simplificación del desarrollo: Node.js, por sí solo, requiere escribir mucho código repetitivo para tareas comunes como el manejo de rutas, procesamiento de peticiones HTTP, o servir archivos estáticos. Express elimina esta complejidad proporcionando una API intuitiva y bien diseñada.

// Sin Express (Node.js puro) - más código y complejidad
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
  const parsedUrl = url.parse(req.url, true);
  
  if (req.method === 'GET' && parsedUrl.pathname === '/') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>Hola Mundo</h1>');
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('No encontrado');
  }
});

// Con Express - más limpio y mantenible
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('<h1>Hola Mundo</h1>');
});

Ecosistema maduro y confiable: Con más de 17 millones de descargas semanales en npm, Express cuenta con una comunidad activa y un ecosistema de middleware extenso. Esto significa que para casi cualquier funcionalidad que necesites, probablemente ya existe una solución probada y mantenida por la comunidad.

Rendimiento optimizado: Express está construido sobre Node.js y aprovecha su arquitectura asíncrona y orientada a eventos. El framework añade una sobrecarga mínima, manteniendo la velocidad y eficiencia que caracteriza a Node.js, especialmente importante para aplicaciones que manejan muchas conexiones simultáneas.

Flexibilidad para cualquier tipo de proyecto: Express se adapta perfectamente tanto para APIs REST como para aplicaciones web tradicionales. Su naturaleza modular permite agregar únicamente las funcionalidades que necesitas, desde autenticación hasta procesamiento de formularios o integración con bases de datos.

Express en 2025: Evolución continua

La versión 5.0 de Express, lanzada oficialmente en octubre de 2024, marca un hito importante en la evolución del framework. Esta versión introduce mejoras significativas en seguridad, rendimiento y compatibilidad con las versiones modernas de Node.js (desde la v18 en adelante).

Entre las mejoras más relevantes se encuentran un sistema de rutas simplificado, mejor integración con las características modernas de JavaScript, y un enfoque renovado en la seguridad con la incorporación de herramientas como CodeQL para la detección automática de vulnerabilidades.

Express continúa siendo la opción preferida para desarrolladores que buscan un equilibrio perfecto entre simplicidad y potencia, proporcionando las herramientas necesarias para construir desde APIs sencillas hasta aplicaciones web empresariales complejas.

Instalación y configuración inicial

La instalación de Express en un proyecto Node.js es un proceso sencillo que requiere unos pocos pasos fundamentales. Antes de comenzar, es importante asegurarnos de que tenemos Node.js versión 18 o superior instalado en nuestro sistema, ya que Express 5.0 requiere estas versiones modernas para aprovechar las características más recientes del lenguaje.

Creación del proyecto

El primer paso consiste en crear una estructura básica para nuestro proyecto. Abrimos la terminal y ejecutamos los siguientes comandos para crear un directorio y posicionarnos en él:

mkdir mi-aplicacion-express
cd mi-aplicacion-express

Una vez dentro del directorio del proyecto, necesitamos inicializar un proyecto Node.js. Esto se hace mediante el comando npm init, que creará el archivo package.json que contiene toda la información y configuración de nuestro proyecto:

npm init -y

El parámetro -y acepta automáticamente todas las opciones predeterminadas, creando un archivo package.json básico. Este archivo es el centro de control de nuestro proyecto, donde se definen las dependencias, scripts de ejecución y metadatos del proyecto.

Instalación de Express

Con el proyecto inicializado, podemos proceder a instalar Express como dependencia. Ejecutamos el siguiente comando:

npm install express

Este comando descarga Express y lo añade automáticamente al apartado dependencies de nuestro archivo package.json. También crea la carpeta node_modules donde se almacenan todas las librerías que utiliza nuestro proyecto.

Tras la instalación, nuestro package.json se verá similar a esto:

{
  "name": "mi-aplicacion-express",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "express": "^5.1.0"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Configuración de scripts de desarrollo

Para facilitar el desarrollo, es recomendable configurar scripts personalizados en el archivo package.json. Modificamos la sección scripts para incluir comandos útiles:

{
  "scripts": {
    "start": "node index.js",
    "dev": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

El script start es el comando estándar para ejecutar aplicaciones Node.js en producción, mientras que dev nos servirá para desarrollo. Más adelante, cuando conozcamos herramientas como nodemon, podremos mejorar este script para que reinicie automáticamente la aplicación cuando detecte cambios en el código.

Estructura de archivos recomendada

Para proyectos Express, es conveniente seguir una estructura de archivos organizada desde el inicio. Una estructura básica podría ser:

mi-aplicacion-express/
├── index.js          # Punto de entrada de la aplicación
├── package.json      # Configuración del proyecto
├── node_modules/     # Dependencias (generado automáticamente)
└── .gitignore       # Archivos a ignorar por Git

Es importante crear un archivo .gitignore para evitar que node_modules y otros archivos innecesarios se suban a nuestro repositorio:

node_modules/
.env
*.log

Verificación de la instalación

Para confirmar que Express se ha instalado correctamente, podemos verificar la versión instalada ejecutando:

npm list express

Este comando nos mostrará la versión de Express instalada en nuestro proyecto. Si todo ha ido bien, deberíamos ver algo como:

mi-aplicacion-express@1.0.0 /ruta/al/proyecto
└── express@5.1.0

Consideraciones sobre versiones

Express 5.0 representa un cambio significativo respecto a versiones anteriores, especialmente en cuanto a compatibilidad con Node.js. Al requerir Node.js 18 o superior, aprovecha características modernas como Array.flat() y path.isAbsolute() que anteriormente requerían dependencias externas.

Esta modernización del código base no solo mejora el rendimiento, sino que también reduce la superficie de ataque en términos de seguridad, al eliminar dependencias de terceros que podrían contener vulnerabilidades.

Con esta configuración inicial completada, nuestro proyecto está listo para comenzar a desarrollar con Express. El siguiente paso será crear nuestro primer servidor y definir las rutas básicas que darán vida a nuestra aplicación web.

Crear un servidor básico

Con Express instalado y configurado correctamente, podemos proceder a crear nuestro primer servidor web. Este proceso implica escribir el código que define cómo nuestra aplicación responderá a las peticiones HTTP que reciba.

Estructura del archivo principal

Comenzamos creando el archivo principal de nuestra aplicación. Por convención, este archivo suele llamarse index.js o app.js. Creamos el archivo index.js en la raíz de nuestro proyecto:

const express = require('express');
const app = express();
const PORT = 3000;

// Aquí definiremos nuestras rutas

app.listen(PORT, () => {
  console.log(`Servidor ejecutándose en http://localhost:${PORT}`);
});

Este código constituye la base fundamental de cualquier aplicación Express. Primero importamos Express y creamos una instancia de la aplicación mediante express(). Esta instancia, almacenada en la variable app, será nuestro punto de control central.

Definición de rutas básicas

Una ruta en Express define cómo la aplicación responde a una petición del cliente hacia un endpoint específico. Un endpoint se compone de una URL y un método HTTP particular (GET, POST, PUT, DELETE, etc.).

Añadimos una ruta básica que responda a peticiones GET en la ruta raíz:

const express = require('express');
const app = express();
const PORT = 3000;

// Ruta básica para la página principal
app.get('/', (req, res) => {
  res.send('¡Hola mundo desde Express!');
});

app.listen(PORT, () => {
  console.log(`Servidor ejecutándose en http://localhost:${PORT}`);
});

El método app.get() define una ruta que responde únicamente a peticiones HTTP GET. El primer parámetro ('/') especifica la URL, mientras que el segundo es una función callback que se ejecuta cuando se recibe una petición que coincide con esa ruta.

La función callback recibe dos parámetros importantes:

  • req (request): Contiene información sobre la petición HTTP entrante
  • res (response): Proporciona métodos para enviar la respuesta al cliente

Múltiples rutas y respuestas

Podemos definir múltiples rutas para crear diferentes endpoints en nuestra aplicación:

const express = require('express');
const app = express();
const PORT = 3000;

// Página principal
app.get('/', (req, res) => {
  res.send('¡Bienvenido a mi aplicación Express!');
});

// Página de información
app.get('/acerca', (req, res) => {
  res.send('<h1>Acerca de nosotros</h1><p>Esta es una aplicación web construida con Express.js</p>');
});

// API endpoint que devuelve JSON
app.get('/api/datos', (req, res) => {
  res.json({
    mensaje: 'Hola desde la API',
    timestamp: new Date().toISOString(),
    version: '1.0.0'
  });
});

app.listen(PORT, () => {
  console.log(`Servidor ejecutándose en http://localhost:${PORT}`);
});

En este ejemplo, utilizamos diferentes métodos de respuesta:

  • res.send(): Envía una respuesta que puede ser texto, HTML o JSON
  • res.json(): Específicamente para enviar respuestas en formato JSON

Configuración avanzada del puerto

Para hacer nuestra aplicación más flexible y preparada para producción, podemos configurar el puerto de forma que pueda adaptarse a diferentes entornos:

const express = require('express');
const app = express();

// Puerto dinámico que se adapta al entorno
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    mensaje: 'Servidor funcionando correctamente',
    puerto: PORT,
    entorno: process.env.NODE_ENV || 'development'
  });
});

// Manejo de errores en el servidor
app.listen(PORT, (error) => {
  if (error) {
    console.error('Error al iniciar el servidor:', error);
    process.exit(1);
  }
  console.log(`✅ Servidor iniciado exitosamente`);
  console.log(`🌐 Accede a: http://localhost:${PORT}`);
  console.log(`⏰ Iniciado en: ${new Date().toLocaleString()}`);
});

Esta configuración utiliza variables de entorno para determinar el puerto, lo que es especialmente útil cuando desplegamos la aplicación en servicios como Heroku, Vercel o AWS, donde el puerto se asigna dinámicamente.

Ejecución y verificación del servidor

Para ejecutar nuestro servidor, utilizamos el comando Node.js desde la terminal:

node index.js

Si todo funciona correctamente, veremos en la consola el mensaje de confirmación que programamos. Podemos entonces abrir un navegador web y navegar a http://localhost:3000 para ver nuestra aplicación en funcionamiento.

Para verificar que las diferentes rutas funcionan, podemos acceder a:

  • http://localhost:3000/ - Página principal
  • http://localhost:3000/acerca - Página de información
  • http://localhost:3000/api/datos - Endpoint de API

Manejo de rutas no encontradas

Es una buena práctica implementar un manejador para rutas que no existen en nuestra aplicación:

// ... otras rutas ...

// Manejador para rutas no encontradas (debe ir al final)
app.get('*', (req, res) => {
  res.status(404).json({
    error: 'Página no encontrada',
    ruta: req.path,
    mensaje: 'La ruta solicitada no existe en este servidor'
  });
});

app.listen(PORT, (error) => {
  if (error) {
    console.error('Error al iniciar el servidor:', error);
    process.exit(1);
  }
  console.log(`Servidor funcionando en http://localhost:${PORT}`);
});

El asterisco (*) actúa como comodín que coincide con cualquier ruta no definida previamente. Es importante colocar este manejador al final del archivo, después de todas las rutas específicas, ya que Express evalúa las rutas en el orden en que se definen.

Con estos fundamentos, tenemos un servidor Express completamente funcional que puede manejar peticiones HTTP, servir diferentes tipos de contenido y proporcionar una base sólida para desarrollar aplicaciones web más complejas.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Node

Documentación oficial de Node
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Node es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Node

Explora más contenido relacionado con Node y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender qué es Express y su papel en el ecosistema Node.js.
  • Instalar y configurar un proyecto básico con Express.
  • Crear un servidor web básico y definir rutas HTTP.
  • Manejar rutas no encontradas y configurar el puerto dinámicamente.
  • Conocer las ventajas y características principales de Express 5.0.