Compartir en Twitter
Go to Homepage

CREAR UNA APLICACIÓN DE CHAT CON NODE.JS

October 20, 2025

Introducción a la creación de una aplicación de chat en tiempo real

Node.js ha transformado el desarrollo web al permitir que JavaScript, tradicionalmente utilizado en el lado del cliente, se ejecute también en el servidor. Esta capacidad, combinada con frameworks como Express.js y herramientas como Socket.io, permite crear aplicaciones dinámicas, como un chat en tiempo real que no requiere recargar la página para actualizar mensajes. En este tutorial, desarrollaremos una aplicación de chat en tiempo real que permite a múltiples usuarios intercambiar mensajes de manera instantánea, utilizando Node.js, Express, Mongoose y Socket.io. Este proyecto es ideal para programadores que desean explorar el desarrollo backend con JavaScript y aprender a implementar soluciones modernas de comunicación en tiempo real.

Node.js es un entorno de ejecución de JavaScript de código abierto y multiplataforma que permite ejecutar código fuera del navegador. Su principal ventaja es que unifica el uso de JavaScript tanto en el frontend como en el backend, simplificando el desarrollo. A diferencia de los entornos tradicionales, Node.js utiliza un modelo de entrada/salida no bloqueante, lo que lo hace eficiente para operaciones como la lectura de archivos o el manejo de solicitudes HTTP. Este modelo asíncrono, basado en callbacks, eventos y promesas, es ideal para aplicaciones que requieren alta concurrencia, como los chats en tiempo real.

Para comenzar, necesitamos instalar Node.js. Puedes descargarlo desde el sitio oficial en nodejs.org. Asegúrate de instalar la versión LTS para garantizar estabilidad. Una vez instalado, verifica la instalación ejecutando el siguiente comando en tu terminal:

node -v
npm -v

Esto mostrará las versiones de Node.js y npm (el gestor de paquetes de Node.js). Con Node.js configurado, podemos proceder a crear nuestra aplicación.

Configuración inicial del proyecto

Para iniciar, crearemos un directorio para nuestro proyecto y lo configuraremos con npm. Este proceso genera un archivo package.json, que gestiona las dependencias y configuraciones del proyecto. Ejecuta los siguientes comandos:

mkdir chat-app
cd chat-app
npm init -y

El comando npm init -y crea un archivo package.json con valores predeterminados. El archivo resultante tendrá una estructura similar a esta:

{
    "name": "chat-app",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

Este archivo será el núcleo de nuestro proyecto, donde se registrarán las dependencias que instalemos. A continuación, instalaremos Express.js, un framework ligero para Node.js que simplifica la creación de servidores web.

Instalación y configuración de Express.js

Express.js es un framework minimalista que proporciona herramientas robustas para construir aplicaciones web. Para instalarlo, ejecuta:

npm install express --save

Esto agrega Express como una dependencia en package.json. Ahora, crearemos un archivo server.js para configurar el servidor. El siguiente código inicializa un servidor Express que escucha en el puerto 3000:

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

const server = app.listen(3000, () => {
    console.log("Servidor corriendo en el puerto", server.address().port);
});

Guarda este código en server.js. Para probarlo, ejecuta:

node server.js

Si todo está correcto, verás el mensaje “Servidor corriendo en el puerto 3000”. Este servidor básico es el punto de partida para nuestra aplicación de chat en tiempo real. Ahora, necesitamos una interfaz de usuario para que los usuarios interactúen con el chat.

Creación de la interfaz de usuario

La interfaz de usuario será una página HTML simple que permita a los usuarios ingresar su nombre y mensaje, y ver los mensajes enviados. Crearemos un archivo index.html en el directorio raíz del proyecto con el siguiente contenido:

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Chat en Tiempo Real</title>
        <link
            href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
            rel="stylesheet"
        />
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <div class="container">
            <br />
            <div class="jumbotron bg-light p-4">
                <h1 class="display-4">Enviar Mensaje</h1>
                <br />
                <input id="name" class="form-control" placeholder="Nombre" />
                <br />
                <textarea
                    id="message"
                    class="form-control"
                    placeholder="Tu mensaje aquí"
                ></textarea>
                <br />
                <button id="send" class="btn btn-success">Enviar</button>
            </div>
            <div id="messages" class="mt-4"></div>
        </div>
        <script>
            // Código JavaScript del cliente se agregará más adelante
        </script>
    </body>
</html>

Para servir este archivo estático con Express, modificaremos server.js para incluir el middleware de archivos estáticos:

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

// Servir archivos estáticos desde el directorio raíz
app.use(express.static(__dirname));

const server = app.listen(3000, () => {
    console.log("Servidor corriendo en el puerto", server.address().port);
});

Ahora, al visitar http://localhost:3000/index.html en tu navegador, deberías ver la interfaz del chat. El siguiente paso es implementar la funcionalidad de comunicación en tiempo real con Socket.io.

Implementación de Socket.io para comunicación en tiempo real

Socket.io es una biblioteca que permite la comunicación bidireccional en tiempo real entre el cliente y el servidor mediante WebSockets. Para instalar Socket.io, ejecuta:

npm install socket.io --save

Actualizaremos server.js para integrar Socket.io con nuestro servidor Express:

const express = require("express");
const app = express();
const server = app.listen(3000, () => {
    console.log("Servidor corriendo en el puerto", server.address().port);
});

app.use(express.static(__dirname));

const io = require("socket.io")(server);

io.on("connection", (socket) => {
    console.log("Nuevo usuario conectado");

    socket.on("sendMessage", (data) => {
        io.emit("message", data);
    });

    socket.on("disconnect", () => {
        console.log("Usuario desconectado");
    });
});

En este código, inicializamos Socket.io con el servidor Express y escuchamos eventos de conexión. Cuando un usuario envía un mensaje (evento sendMessage), lo retransmitimos a todos los clientes conectados con el evento message. Ahora, necesitamos agregar la lógica del lado del cliente en index.html para interactuar con Socket.io. Agrega el siguiente script dentro de la etiqueta <script> en index.html:

<script src="/socket.io/socket.io.js"></script>
<script>
    $(document).ready(function () {
        const socket = io();

        $("#send").click(function () {
            const name = $("#name").val();
            const message = $("#message").val();
            if (name && message) {
                socket.emit("sendMessage", { name, message });
                $("#message").val("");
            }
        });

        socket.on("message", function (data) {
            $("#messages").append(
                `<div class="card mb-2">
          <div class="card-body">
            <strong>${data.name}</strong>: ${data.message}
          </div>
        </div>`
            );
        });
    });
</script>

Este código conecta el cliente al servidor Socket.io, envía mensajes cuando se hace clic en el botón “Enviar” y muestra los mensajes recibidos en el contenedor #messages. Ahora, la aplicación permite a los usuarios enviar y recibir mensajes en tiempo real.

Integración de Mongoose para persistencia de datos

Para almacenar los mensajes en una base de datos, utilizaremos Mongoose, una biblioteca que facilita la interacción con MongoDB, una base de datos NoSQL ideal para aplicaciones JavaScript. Primero, asegúrate de tener MongoDB instalado y ejecutándose localmente o usa un servicio en la nube como MongoDB Atlas. Instala Mongoose con:

npm install mongoose --save

Crea un archivo models/Message.js para definir el esquema de los mensajes:

const mongoose = require("mongoose");

const messageSchema = new mongoose.Schema({
    name: String,
    message: String,
    timestamp: { type: Date, default: Date.now },
});

module.exports = mongoose.model("Message", messageSchema);

Actualiza server.js para conectar con MongoDB y guardar los mensajes:

const express = require("express");
const mongoose = require("mongoose");
const Message = require("./models/Message");

const app = express();
const server = app.listen(3000, () => {
    console.log("Servidor corriendo en el puerto", server.address().port);
});

app.use(express.static(__dirname));

// Conectar a MongoDB
mongoose
    .connect("mongodb://localhost:27017/chat-app", {
        useNewUrlParser: true,
        useUnifiedTopology: true,
    })
    .then(() => {
        console.log("Conectado a MongoDB");
    })
    .catch((err) => {
        console.error("Error al conectar a MongoDB:", err);
    });

const io = require("socket.io")(server);

io.on("connection", async (socket) => {
    console.log("Nuevo usuario conectado");

    // Cargar mensajes existentes
    const messages = await Message.find().sort({ timestamp: -1 }).limit(50);
    socket.emit("loadMessages", messages.reverse());

    socket.on("sendMessage", async (data) => {
        const message = new Message({
            name: data.name,
            message: data.message,
        });
        await message.save();
        io.emit("message", message);
    });

    socket.on("disconnect", () => {
        console.log("Usuario desconectado");
    });
});

Modifica el script en index.html para manejar la carga de mensajes existentes:

<script src="/socket.io/socket.io.js"></script>
<script>
    $(document).ready(function () {
        const socket = io();

        $("#send").click(function () {
            const name = $("#name").val();
            const message = $("#message").val();
            if (name && message) {
                socket.emit("sendMessage", { name, message });
                $("#message").val("");
            }
        });

        socket.on("message", function (data) {
            $("#messages").append(
                `<div class="card mb-2">
          <div class="card-body">
            <strong>${data.name}</strong>: ${data.message}
          </div>
        </div>`
            );
        });

        socket.on("loadMessages", function (messages) {
            messages.forEach(function (data) {
                $("#messages").append(
                    `<div class="card mb-2">
            <div class="card-body">
              <strong>${data.name}</strong>: ${data.message}
            </div>
          </div>`
                );
            });
        });
    });
</script>

Con estos cambios, los mensajes se almacenan en MongoDB y se cargan al conectar un nuevo usuario, mostrando hasta los últimos 50 mensajes.

Optimización y mejoras

Para mejorar la experiencia del usuario, podemos agregar algunas funcionalidades adicionales. Por ejemplo, podemos mostrar una notificación cuando un usuario se conecta o desconecta. Actualiza el código de Socket.io en server.js:

io.on("connection", async (socket) => {
    console.log("Nuevo usuario conectado");
    io.emit("notification", { message: "Un nuevo usuario se ha conectado" });

    const messages = await Message.find().sort({ timestamp: -1 }).limit(50);
    socket.emit("loadMessages", messages.reverse());

    socket.on("sendMessage", async (data) => {
        const message = new Message({
            name: data.name,
            message: data.message,
        });
        await message.save();
        io.emit("message", message);
    });

    socket.on("disconnect", () => {
        console.log("Usuario desconectado");
        io.emit("notification", { message: "Un usuario se ha desconectado" });
    });
});

Y en index.html, agrega un manejador para las notificaciones:

socket.on('notification', function(data) { $('#messages').append( `
<div class="alert alert-info mb-2">${data.message}</div>
` ); });

Esto mostrará alertas en la interfaz cuando los usuarios se conecten o desconecten. Además, considera agregar validación para evitar mensajes vacíos o nombres demasiado largos, y estilizar la interfaz para mejorar la experiencia del usuario.

Despliegue de la aplicación

Para desplegar la aplicación, puedes usar plataformas como Heroku, Vercel o Render. Asegúrate de configurar las variables de entorno para la conexión a MongoDB y el puerto del servidor. Por ejemplo, en server.js, puedes usar una variable de entorno para el puerto:

const port = process.env.PORT || 3000;
const server = app.listen(port, () => {
    console.log("Servidor corriendo en el puerto", server.address().port);
});

Para MongoDB en producción, utiliza un servicio como MongoDB Atlas y configura la URI de conexión como una variable de entorno. Por ejemplo:

mongoose.connect(process.env.MONGODB_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});

Asegúrate de que tu proveedor de alojamiento soporta WebSockets para Socket.io. La mayoría de las plataformas modernas, como Vercel, lo hacen por defecto.

Conclusiones

La creación de una aplicación de chat en tiempo real con Node.js, Express, Mongoose y Socket.io demuestra el poder de JavaScript como un lenguaje unificado para el desarrollo full-stack. Este tutorial cubrió la configuración de un servidor Express, la implementación de comunicación en tiempo real con Socket.io, la persistencia de datos con Mongoose y MongoDB, y mejoras para optimizar la experiencia del usuario. Con estas herramientas, puedes construir aplicaciones web dinámicas y escalables. Para proyectos futuros, considera agregar autenticación, salas de chat privadas o notificaciones push para mejorar la funcionalidad. Experimenta con el código, personaliza la interfaz y despliega tu aplicación para compartirla con el mundo.