Autenticación en Next.js: Auth.js vs Better Auth vs Clerk | We.Inc
Compara Auth.js, Better Auth, Clerk, Supabase Auth y una sesión hecha a mano para Next.js 16, con el código de configuración de cada una y un selector que reduce la lista según lo que necesitas.
Opciones de autenticación en Next.js comparadas
En la mayoría de las apps de Next.js, elige una librería en lugar de escribir la autenticación tú mismo. Clerk es un servicio alojado y el más rápido de configurar, Supabase Auth encaja con apps que ya usan Supabase, y Better Auth o Auth.js guardan los usuarios en tu propia base de datos. Elijas lo que elijas, vuelve a comprobar la sesión en el código de servidor, porque las comprobaciones en el proxy por sí solas no protegen los datos.
De un vistazo
Opción
Dónde se guardan los usuarios
Clerk
Los servidores de Clerk
@clerk/nextjs, ClerkProvider, clerkMiddleware en proxy.ts
Supabase Auth
Tu proyecto de Supabase
Clientes de @supabase/ssr más un proxy que refresca la sesión
Better Auth
Tu propia base de datos
Instancia de auth más app/api/auth/[...all]/route.ts
Auth.js (next-auth v5 beta)
Tu base de datos o una cookie JWT
auth.ts más app/api/auth/[...nextauth]/route.ts
Hazlo tú mismo
Tu propia base de datos
jose o iron-session, cookies httpOnly y una capa de acceso a datos
La guía oficial de Next.js enumera doce librerías de autenticación compatibles, más opciones de las que la mayoría quiere. Esta comparativa lo reduce a las cinco vías que de verdad sopesan la mayoría de los equipos, muestra el código mínimo de cada una en el App Router y explica las comprobaciones que tu app sigue necesitando, sea cual sea la librería que gestiona el inicio de sesión.
Marca los requisitos que te importan, como guardar los datos de los usuarios en tu propia base de datos o tener pantallas de inicio de sesión ya hechas.
El selector oculta las opciones que no cumplen todos los requisitos marcados.
Abre el código de configuración de las opciones que quedan y compara cuánto tendrías que escribir.
Lee la sección de seguridad antes de publicar, elijas la opción que elijas.
Guarda las sesiones en cookies creadas en el servidor con HttpOnly, Secure, SameSite y una caducidad, como recomienda la guía de Next.js.
Pon una función verifySession() en un único archivo solo de servidor y llámala desde las páginas, las Server Actions y los Route Handlers.
No confíes en un layout para las comprobaciones de autenticación. Los layouts no se vuelven a renderizar en la navegación del cliente, así que la comprobación puede saltarse.
Mantén pequeño el contenido de la sesión: un id de usuario y un rol, nunca un email ni un número de teléfono.
Genera los secretos con openssl rand -base64 32 (o npx auth secret para Auth.js) y guárdalos en variables de entorno.
Preguntas frecuentes
¿Se sigue manteniendo NextAuth?
Auth.js, el proyecto antes llamado NextAuth, dice en su propio sitio que ahora forma parte de Better Auth. Su comando de instalación para Next.js sigue siendo npm install next-auth@beta. Los proyectos nuevos suelen empezar directamente con Better Auth, mientras que las apps existentes con Auth.js siguen funcionando.
¿Puedo proteger las páginas solo con proxy.ts?
No. La documentación de Next.js califica de optimistas las comprobaciones en el proxy: sirven para redirecciones rápidas basadas en una cookie, pero no son una barrera de seguridad. Vuelve a verificar la sesión cerca de los datos, porque las Server Functions y las rutas fuera del matcher nunca pasan por el proxy.
¿Qué opción es la más barata?
Las librerías que guardan los usuarios en tu propia base de datos, como Better Auth o Auth.js, no cobran por usuario; pagas tu base de datos y el envío de emails. Supabase Auth incluye 50,000 usuarios activos mensuales en el plan gratuito a fecha de octubre de 2026. Consulta la página de precios de Clerk para ver su cuota gratuita actual.
¿Funcionan con Next.js 16?
Sí. Tanto Clerk como Supabase documentan proxy.ts para Next.js 16 y middleware.ts para versiones anteriores, y Better Auth ofrece un helper de cookies para el proxy más una comprobación completa de la sesión para el código de servidor.
¿Sesiones sin estado o en base de datos?
Una cookie firmada (sin estado) es más sencilla y no necesita consultas, pero no puedes revocarla antes de que caduque. Una sesión en base de datos cuesta una consulta por comprobación y permite a los usuarios cerrar sesión en todos sus dispositivos. Muchas librerías te dejan elegir.
Alojado frente a autoalojado
Clerk gestiona por ti el almacén de usuarios, las páginas de inicio de sesión y las sesiones, y tú colocas sus componentes en tu layout. Cambias algo de control y una factura mensual cuando creces por rapidez y una interfaz pulida desde el primer día.
Better Auth y Auth.js se ejecutan dentro de tu app y escriben en tu base de datos. Los datos y las pantallas son tuyos, y también el envío de emails, los flujos de restablecimiento de contraseña y las actualizaciones.
Si ya usas Supabase
Supabase Auth vincula el inicio de sesión directamente con la seguridad a nivel de fila de Postgres, así que una política como auth.uid() = user_id protege los datos en la capa de base de datos. El paquete @supabase/ssr guarda la sesión en cookies para que los Server Components puedan leerla.
La documentación de Supabase advierte de que getSession() devuelve datos sin verificar. Usa getClaims(), que comprueba la firma del token, o getUser(), que consulta al servidor de autenticación, antes de fiarte de quién es el usuario.
Escribir la tuya
La guía de Next.js lo explica paso a paso con una Server Action para el formulario, Zod para la validación, bcrypt para el hash y jose para firmar una cookie de sesión de siete días. Es una buena forma de aprender todas las piezas.
Para producción, la misma guía recomienda una librería, porque la limitación de peticiones, la verificación de email, la vinculación de cuentas y el inicio de sesión multifactor se acumulan rápido.
Configuración mínima de cada opción
Clerk
Instala @clerk/nextjs y define NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY y CLERK_SECRET_KEY. En Next.js 16 el archivo de middleware es proxy.ts.
Supabase Auth
Un cliente de servidor creado en cada petición a partir del almacén de cookies, con la clave publicable. getClaims() verifica el token antes de que te fíes de él.
Better Auth
Monta el handler en una ruta catch-all y luego lee la sesión en el servidor con las cabeceras de la petición.