Chatify
Una app de mensajería en tiempo real que construí en solitario en TypeScript, de la interfaz al servidor. Chats uno a uno con texto, archivos, imágenes, videos, stickers, GIFs, emojis, reacciones y confirmación de lectura, con más de 200 registros.
- Rol
- Desarrollador full stack, en solitario
- Año
- 2024
- Tiempo real
- Socket.io
- Datos
- Turso, S3
Dos sesiones lado a lado: la mía y un contacto de ejemplo. La conversación se reproduce automáticamente con los eventos del socket abajo. Todo corre localmente con datos de ejemplo.
01
Lo que hace falta para sentirse instantáneo
Quería entender qué hace falta para construir una app de mensajería que se sienta como las que usamos todos los días: entrega inmediata, multimedia, confirmación de lectura y esas pequeñas acciones que uno espera.
REST carga los chats y el historial. Socket.io se encarga de la entrega en vivo. Ambos lados se protegen con el mismo JWT de Auth0.
Socket.io
De una ventana a la otra
02
Los detalles que completan un chat
Más allá de enviar texto, la mayor parte del trabajo estuvo en los detalles.
El chat
Lo que cabe en una conversación
Funciones
AhoraEnlaces clicables, imágenes, videos y cualquier archivo con vista previa, más un selector de stickers y GIFs con Tenor.
AhoraResponde a un mensaje concreto y vuelve a él desde la cita.
AhoraReacciona a cualquier mensaje con un emoji.
AhoraMarcas de lectura de enviado, entregado y leído, y avisos de mensajes sin ver.
AhoraFijar, ocultar, silenciar, marcar como no leído, bloquear, vaciar o eliminar un chat.
AhoraEncuentra chats y mensajes, y filtra lo compartido por archivos y multimedia.
- Mensajes ricos
- Respuestas
- Reacciones
- Estado de lectura
- Acciones del chat
- Búsqueda
Lo construí completo: cliente, API, capa de tiempo real, modelo de datos, manejo de archivos, CI y el pipeline de despliegue.
03
Un servidor siempre encendido, a propósito
El repo es un workspace de pnpm con un cliente en React y una API en Node.js. El cliente está en Cloudflare Pages. Las conexiones en tiempo real necesitan un proceso que no se apague, así que la API corre en AWS EC2 con PM2 y se despliega con GitHub Actions.
01 · Cliente
React + Vite
Zustand para el estado y Dexie para almacenamiento local.
Auth0
Acceso con Google, GitHub o correo. Un solo JWT para REST y sockets.
02 · API
Express
Rutas REST protegidas con express-oauth2-jwt-bearer.
Socket.io
Entra new_message, sale chat_message, detrás de authSocketMiddleware.
03 · Datos e infraestructura
Turso (libSQL)
Usuarios, chats y mensajes.
S3 + CloudFront
Subida de archivos con URLs firmadas opcionales.
EC2 + PM2
Corre la API, desplegada desde GitHub Actions.
Decisiones
- 01
Socket.io en un servidor que no se apaga
Las conexiones en tiempo real necesitan un proceso activo, así que la API corre en EC2 con PM2 en vez de funciones serverless.
- 02
Archivos en S3, no en la base de datos
Los archivos van a almacenamiento de objetos y en Turso solo quedan las referencias, así la base de datos se mantiene liviana.
- 03
Un solo modelo de autenticación
Usar el mismo JWT de Auth0 en REST y sockets deja un solo lugar donde decidir quién puede hacer qué.
Pruébalo
Chatify está en vivo y el código está en GitHub con licencia MIT.