Cuando hablamos de tener un backend listo y conectarlo directamente con un frontend o una app móvil, lo primero que viene a la cabeza es Supabase. Es uno de los proyectos más populares para tener un backend prearmado sin partir desde cero.
Pero estos días también tenemos Convex, otro proyecto open source con servicio autoalojado que tiene cosas bastante interesantes:
- Tiempo real por defecto (sin configurar WebSockets ni nada).
- Subida de archivos y autenticación integradas.
- Skills oficiales para que tu agente de IA (Claude Code, Codex, Cursor) escriba código siguiendo las mejores prácticas del proyecto.
Si no te llevas con Supabase o quieres conocer otra opción para tus prototipos y MVPs, vale la pena darle una mirada. En este artículo te voy a dar un overview, instalarlo desde cero y construir un Todo + chat para ver cómo se siente trabajar con él.
🔗 Web oficial: convex.dev 🔗 Repos open source: github.com/get-convex
¿Qué es Convex?
Convex es un Backend as a Service (BaaS) similar a Supabase o Firebase. Te provee:
- Una base de datos document-relational (algo entre Mongo y Postgres).
- Funciones de servidor escritas en TypeScript (queries, mutations y actions).
- Cliente con suscripciones en tiempo real vía WebSocket.
- Storage de archivos.
- Autenticación.
- Búsquedas, cron jobs, scheduling.
La gran diferencia con Supabase es que no escribes SQL: todas tus consultas son funciones TypeScript que viven en una carpeta convex/ dentro de tu proyecto. Y cuando un dato cambia, los componentes React que lo consumen se actualizan automáticamente.
Instalación desde cero
Convex soporta los frameworks más populares (Next.js, Vite, Expo, Svelte, etc.). En este caso lo voy a usar con Next.js.
Necesitas Node 18+ y arrancas creando un proyecto Next como cualquier otro:
npx create-next-app@latest mi-app
cd mi-app
Y ahora sí instalas Convex:
npm install convex
npx convex dev
El comando npx convex dev configura el entorno. Te da dos opciones:
- Iniciar Convex localmente (sin cuenta, todo corre en tu máquina).
- Login y crear cuenta (recomendado si vas a pasar a producción).
Si vas a hacer algo real, te recomiendo el login: te da una URL desplegada gratis, dashboard online y luego solo necesitas conectar tu app cuando quieras subirla.
Después del login, te pide un nombre de proyecto, la región y configura los skills para los agentes de IA.
La carpeta convex/ y los skills para IA
Una vez configurado, Convex te genera la carpeta convex/ con esta estructura:
convex/
├── _generated/ # Tipos y clientes autogenerados
├── ai/
│ └── guidelines.md # Cómo debe escribir código tu agente
└── schema.ts # Aquí defines las tablas
Y además crea dos carpetas de skills duplicadas en la raíz del proyecto:
.cursor/— para Cursor, VS Code, Antigravity, Codex, etc..claude/— para Claude Code (que no lee.cursor).
Sí, son los mismos archivos en dos lugares. El motivo es práctico: cada agente lee skills desde un sitio distinto, así que en vez de pelear con configuraciones, simplemente duplican. Adentro vas a encontrar skills para crear componentes, hacer migraciones, configurar autenticación, etc.
Crear una tabla con Claude Code
En la documentación tienes el flujo manual paso a paso, pero la realidad es que la mayoría va a usar un agente. Yo lo hice con Claude Code, pero con Codex es exactamente lo mismo.
Le pedí algo simple:
/convex crea una tabla todos en convex
El truco aquí es usar slash para invocar el skill directamente (/convex). Puedes pedirlo en lenguaje natural y a veces Claude detecta el skill correcto, pero con muchos skills cargados a veces los interpreta mal o ni los carga. Llamarlo explícitamente es más confiable.
El agente edita convex/schema.ts y crea un archivo convex/todos.ts con las operaciones CRUD encima de esa tabla:
// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
todos: defineTable({
text: v.string(),
completed: v.boolean(),
}),
});
// convex/todos.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
export const list = query({
handler: async (ctx) => {
return await ctx.db.query("todos").collect();
},
});
export const create = mutation({
args: { text: v.string() },
handler: async (ctx, args) => {
await ctx.db.insert("todos", {
text: args.text,
completed: false,
});
},
});
export const toggle = mutation({
args: { id: v.id("todos"), completed: v.boolean() },
handler: async (ctx, args) => {
await ctx.db.patch(args.id, { completed: args.completed });
},
});
Si entras al dashboard de Convex inmediatamente vas a ver la tabla todos creada. Para llenarla con datos de ejemplo, le pedí: "crea un seed de datos para esta tabla" y generó un archivo convex/seed.ts que itera e inserta registros. Lo ejecuta él mismo y la tabla se llena al instante.
Conectar con Next.js
Ya tenemos backend, ahora a conectarlo. De nuevo le delegué a Claude Code:
/convex conéctalo con los datos del backend de convex
Lo que hace por debajo es importar el ConvexProvider y envolver la aplicación entera. Esto inyecta el contexto en cada página para que cualquier componente pueda hacer queries y mutations.
// app/providers.tsx
"use client";
import { ConvexProvider, ConvexReactClient } from "convex/react";
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
export function Providers({ children }: { children: React.ReactNode }) {
return <ConvexProvider client={convex}>{children}</ConvexProvider>;
}
Y en los componentes usas useQuery y useMutation. Si has trabajado con GraphQL la sintaxis te va a sonar:
"use client";
import { useQuery, useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
export default function TodoList() {
const todos = useQuery(api.todos.list);
const toggle = useMutation(api.todos.toggle);
if (!todos) return <p>Cargando...</p>;
return (
<ul>
{todos.map((todo) => (
<li key={todo._id}>
<input
type="checkbox"
checked={todo.completed}
onChange={(e) =>
toggle({ id: todo._id, completed: e.target.checked })
}
/>
{todo.text}
</li>
))}
</ul>
);
}
useQuery consulta datos. useMutation los modifica (crear, actualizar, eliminar). Y ya está conectado.
Tiempo real por defecto
Esto es lo que más me gustó. Si abres dos pestañas del navegador y marcas un todo en una, en la otra se actualiza al instante. Y en el dashboard de Convex también ves la animación de las filas actualizándose en vivo.
No tuve que configurar nada de WebSockets, ni Pusher, ni Ably. El cliente de Convex ya hace todo el trabajo. La documentación de tiempo real prácticamente no existe porque… no hay nada que configurar.
Para probarlo más a fondo, le pedí al agente que cree un chat flotante:
crea un chat flotante en la parte inferior izquierda
y crea también el backend en Convex para guardar los mensajes
Generó una tabla messages en el schema, su archivo messages.ts con las funciones de listar y enviar, y la UI flotante. Abrí dos ventanas, escribí desde una con un usuario y desde otra como "María", y los mensajes aparecían en ambos lados sin tocar nada más.
Autenticación: el punto débil que están mejorando
Este es el tema donde Convex flaquea un poco frente a Supabase y Firebase. Esos backends ya te dan auth completo de fábrica.
Convex históricamente no tenía un método de autenticación propio. Te apoyabas en proveedores externos:
- Clerk (el más recomendado en su comunidad)
- Auth0
- WorkOS
El problema es que son servicios aparte, con sus propios planes pagos. Si vas a producción terminas pagando dos suscripciones.
Recientemente lanzaron Convex Auth, su propia biblioteca de autenticación. Está en beta pero ya se puede usar. Y como esperarías, también tiene su skill:
/convex setup-auth
El agente te pregunta qué proveedor quieres usar (Convex Auth, Clerk) y si estás en local o producción. De momento Convex Auth ofrece tres formas de autenticar:
- Contraseñas — el típico email + password.
- OAuth — Google, GitHub, etc.
- Magic links — login por correo sin contraseña.
Si la documentación que te muestra el skill se queda corta, en los docs oficiales de Convex Auth describen los métodos con mucho más detalle.
Precios: pagas solo por lo que usas
Aquí Convex tiene un modelo distinto al de Supabase. No te cobra por proyecto, te cobra por consumo de recursos. Cada plan te da ciertos límites:
| Recurso | Free | Pro | Business |
|---|---|---|---|
| Despliegues por mes | 40 | 300 | Ilimitado |
| Llamadas a funciones | 1M / mes | Más generoso | Ilimitado |
| Storage | 1 GB | Más | Más |
| Integraciones (PostHog, Datadog, Sentry) | ❌ | ✅ | ✅ |
Después del límite gratuito te empiezan a cobrar por millón de consultas, por GB extra de storage (~$0.03/GB), etc.
La diferencia con Supabase: en Supabase pagas $25/mes por proyecto. En Convex puedes crear los proyectos que quieras, y solo pagas si efectivamente los usas. Para alguien que tiene varios prototipos o clientes pequeños, esto cambia bastante la matemática.
Open source y self-hosting
Convex es open source y se puede autoalojar. El repo está en github.com/get-convex, específicamente convex-backend. Tiene un contenedor Docker que se levanta clonando el repo, ajustando variables de entorno y listo.
Pero hay consideraciones importantes que conviene leer antes:
- No todo está incluido. Si necesitas storage de archivos tienes que conectar tu propio S3 (o equivalente).
- El self-hosted equivale al plan gratuito. Si quieres las features Pro (integraciones, observabilidad), necesitas pagar.
- Si vas a hacer logs de llamadas a la API o cosas avanzadas, también toca configurar tu propio stack.
Para proyectos internos de empresa donde quieres todo dentro de tu propia infraestructura, sigue siendo una opción viable.
¿Cuándo usar Convex?
Mi resumen después de probarlo:
Úsalo si:
- Estás iniciando un prototipo o MVP y quieres lanzarlo rápido.
- Tu app necesita tiempo real (chat, colaboración, dashboards live, multiplayer).
- Te molesta escribir SQL o configurar ORMs como Prisma/Drizzle.
- Quieres un backend con type-safety completo de extremo a extremo.
- Vas a usar mucho un agente de IA y quieres skills que entiendan tu stack.
Quizás no es para ti si:
- Ya tienes infra establecida con Postgres, Prisma y un backend tradicional.
- Tu app no necesita tiempo real y un CRUD clásico te basta.
- Necesitas auth empresarial robusto desde el día uno (Convex Auth aún está en beta).
- Quieres un ecosistema masivo con muchos tutoriales (todavía no es tan popular como Supabase).
Cierre
Convex es una alternativa sólida que está cerrando rápido la brecha con Supabase. La experiencia de developer es muy buena, especialmente si trabajas con un agente de IA: los skills oficiales hacen que crear tablas, conectarlas con el frontend y configurar autenticación sea cuestión de un par de comandos.
Si te llamó la atención y quieres que cubra temas más específicos, déjamelo en los comentarios. Algunos puntos que se quedaron afuera y que daría para otro artículo:
- Búsquedas (full-text y vectoriales).
- Sección de componentes de Convex (paquetes prefabricados que conectan schema + funciones).
- Self-hosting paso a paso con Docker.
- Comparativa detallada Convex vs Supabase con código equivalente.
Enlaces para que sigas explorando:
- 🔗 convex.dev — sitio oficial.
- 🔗 github.com/get-convex — todos los repos open source.
- 🔗 docs.convex.dev — documentación.
- 🔗 github.com/get-convex/convex-backend — repo del backend autoalojable.
Nos vemos en el siguiente artículo.