CommunityProgramación y desarrollogithub.com

redoy49/nextjs-production-stack

Usa esta skill cuando el usuario solicite construir, generar, extender, revisar o depurar una aplicación Next.js (App Router). Cubre todo el stack de producción: TypeScript, Server Components/Actions, Tailwind + shadcn/ui, React Hook Form + Zod, PostgreSQL + Drizzle, Better Auth, estrategia de caché/renderizado, SEO, accesibilidad, testing, monitoreo, calidad de código y DevOps.

¿Qué es nextjs-production-stack?

Esta skill proporciona un conjunto de convenciones y herramientas recomendadas para construir y mantener aplicaciones Next.js de producción. Está diseñada para desarrolladores que trabajan con Next.js App Router y buscan un stack moderno y eficiente, incluyendo TypeScript, Server Components y Actions, Tailwind CSS con shadcn/ui, React Hook Form con Zod para formularios, PostgreSQL con Drizzle ORM para la base de datos, y Better Auth para autenticación. La skill también cubre aspectos críticos como optimización de rendimiento, SEO, accesibilidad, testing con Vitest y Playwright, monitoreo con Sentry, y DevOps con GitHub Actions y despliegue en Vercel. Funciona como una guía de mejores prácticas que se activa automáticamente cuando el usuario menciona tareas relacionadas con Next.js, ayudando a mantener coherencia en el código y evitando decisiones técnicas no consultadas.

Compatible con✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/redoy49/agent-skills/tree/main/skills/web/nextjs-production-stack

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Stack de Producción Next.js

Valores predeterminados bien pensados para construir y mantener aplicaciones Next.js. Al generar un nuevo proyecto o añadir a uno existente, sigue estas convenciones a menos que el código base existente del usuario haga algo claramente diferente: prioriza los patrones existentes sobre este documento cuando entren en conflicto, y anota brevemente la desviación.

0. Stack de un vistazo

CapaRecomendado (preferido, no estricto)Opciones a ofrecer si se solicita un cambio
FrameworkNext.js (App Router), TypeScript, Server Components + Server Actionsninguno necesario, esto es el núcleo
Gestor de paquetespnpmnpm, yarn, bun
UITailwind CSS, shadcn/ui, react-icons, Motion (motion.dev)Radix UI o Mantine, lucide-react, CSS Modules
FormulariosReact Hook Form + ZodTanStack Form, Valibot en lugar de Zod
Base de datosPostgreSQL + Drizzle ORMPrisma, Kysely; MySQL o SQLite para apps pequeñas
AutenticaciónBetter Auth, RBACAuth.js, Clerk, Supabase Auth
MultimediaCloudinaryUploadThing, S3 + CDN, Vercel Blob
TestingVitest (unit/integración), Playwright (e2e)Jest, Cypress
MonitoreoSentry, logging estructuradoDatadog, Highlight, Axiom + pino
Lint/FormatoESLint, Prettier, TypeScript strictBiome
CI/CDGitHub + GitHub Actions, Vercel, despliegues de vista previaGitLab CI, Netlify, Cloudflare Pages

Nunca cambies silenciosamente un paquete de esta tabla por una alternativa (ej. Prisma en lugar de Drizzle, next-auth en lugar de Better Auth). Si el proyecto del usuario ya usa una opción diferente, continúa usándola y señala la discrepancia en lugar de mezclar dos soluciones para la misma tarea.

Estas herramientas son Recomendadas: el usuario las prefiere, pero no son estrictas.

  • Donde una sección posterior nombre una herramienta específica (pnpm, Drizzle, Better Auth, Cloudinary, Sentry, etc.), léela como el valor predeterminado recomendado bajo esta regla.
  • Antes de cambiar, reemplazar u omitir cualquier herramienta de la tabla, pregunta primero al usuario. Ofrece opciones: mantener la recomendada, o una alternativa de la última columna (u otra mejor práctica), con una línea de compensación para cada una y tu propia recomendación.
  • Verifica el estado actual (mantenimiento, cambios importantes) antes de recomendar una alternativa. No te bases solo en la memoria.
  • Nunca cambies una herramienta sin una respuesta. Hasta que el usuario responda, mantén el valor predeterminado recomendado.

1. Configuración del proyecto

  • Genera con pnpm create next-app@latest — TypeScript, App Router, Tailwind, ESLin todo habilitado, rechaza el directorio src/ para que app/ permanezca en la raíz del proyecto (solo proyectos nuevos).
  • Proyecto existente que ya use src/: mantén src/ — src/app/, src/components/, src/lib/, src/actions/. Usa app/ solo cuando el proyecto no tenga un directorio src/. Sigue el diseño existente y los alias de importación (@/* → src/*); nunca muevas archivos fuera de src/ como parte de una tarea no relacionada.
  • Usa pnpm para cada comando de instalación/ejecución (pnpm add, pnpm dlx, pnpm dev). Nunca mezcles archivos de bloqueo de npm/yarn.
  • Inicializa shadcn/ui mediante pnpm dlx shadcn@latest init, luego añade componentes bajo demanda (pnpm dlx shadcn@latest add button) en lugar de preinstalar todo el conjunto.
  • Forma de carpeta base (sin src/ — app/ está en la raíz del proyecto):
# proyectos nuevos (sin src/)
app/                   # rutas, layouts, límites error/loading/not-found
components/            # UI compartida (ui/ = primitivas shadcn)
lib/                   # db, auth, validaciones, utils, rate-limit, logger
actions/               # server actions agrupadas por dominio
hooks/
types/
drizzle/               # migraciones

Proyectos existentes con src/: misma forma bajo src/ (src/app/, src/components/, src/lib/, src/actions/) — los nombres de carpeta permanecen idénticos, solo cambia el prefijo.

2. TypeScript y calidad de código

  • strict: true en tsconfig, sin any sin un comentario que lo justifique, sin @ts-ignore sin un problema/razón vinculado.
  • ESLint (next/core-web-vitals + typescript-eslint) y Prettier configurados y pasando antes de que el código se considere terminado; ejecútalos, no solo lo asumas.
  • Prefiere tipos de retorno explícitos en funciones exportadas y Server Actions.
  • Mantén los Server Components como predeterminados; añade "use client" solo donde se requiera interactividad, APIs del navegador o hooks, y empuja el límite lo más bajo (lo más hoja) posible.
  • Una responsabilidad por archivo/módulo; coloca las server actions de una ruta en actions/ o en un archivo _actions.ts junto a la ruta, no en línea en archivos de página enormes.
  • Convenciones de arquitectura: mantén un lugar para cada tipo de lógica — acceso a datos en lib/db, mutaciones en actions/, UI compartida en components/, ayudantes transversales en lib/. Sigue la nomenclatura existente del proyecto (carpeta de archivos, nomenclatura de componentes) en lugar de introducir una nueva convención a mitad de camino.
  • Revisión de código: trata cada cambio no trivial como del tamaño de un PR — un diff claro, lint/typecheck/tests pasando antes de solicitar revisión, y una descripción de qué cambió y por qué. Al revisar (humano o asistido por IA), verifica la falta de comprobaciones de autenticación, errores no manejados y desviación de convenciones, no solo si se ejecuta.

3. Renderizado, datos y rendimiento

  • Renderizado estático vs dinámico: predeterminado a estático; opta por dinámico (export const dynamic = 'force-dynamic', cookies(), headers()) solo cuando la ruta genuinamente necesite datos por solicitud.
  • Obtención de datos: obtén datos directamente en Server Components; usa Server Actions para mutaciones, no fetch del lado del cliente a una ruta API a menos que el consumidor sea externo.
  • Streaming y Suspense: envuelve secciones lentas/transmisibles en <Suspense> con un fallback de esqueleto real (no un spinner vacío) para que el resto de la página pueda renderizarse y transmitirse de inmediato — esto también es lo que proporciona loading.tsx a nivel de ruta.
  • Almacenamiento en caché y revalidación: usa use cache / unstable_cache (según la versión de Next) para lecturas costosas; invalida precisamente con revalidatePath / revalidateTag después de mutaciones en lugar de recurrir a force-dynamic para "solucionar" la falta de actualización.
  • Precarga: precarga los enlaces que los usuarios probablemente sigan — <Link> hace esto automáticamente; no lo deshabilites (prefetch={false}) sin una razón específica.
  • Carga diferida y división de código: carga diferida de componentes del lado del cliente que están debajo del pliegue o que se usan con poca frecuencia con next/dynamic; evita grandes paquetes de cliente de bibliotecas que solo se necesitan en una página.
  • Optimización de imágenes y fuentes: usa siempre next/image para imágenes rasterizadas (width/height explícitos o fill + contenedor dimensionado) y next/font para fuentes — nunca <img> sin procesar ni un <link> a Google Fonts.
  • Core Web Vitals: trata LCP, CLS, INP como una restricción real — sin contenido tardío que cause desplazamiento de diseño, sin medios sin dimensionar, sin scripts síncronos bloqueantes.

4. UI

  • Tailwind para estilos; componentes shadcn/ui como primitivas base, personalizadas a través de los tokens de tema del proyecto (variables CSS) en lugar de anulaciones en línea dispersas en archivos.
  • react-icons para iconografía (elige un conjunto de iconos por proyecto, ej. react-icons/lu o /hi2, y mantén la consistencia).
  • Motion (motion.dev, antes Framer Motion) para animaciones; mantén los componentes animados del lado del cliente y pequeños, y respeta prefers-reduced-motion.
  • Diseña con capacidad de respuesta de forma predeterminada (puntos de interrupción de Tailwind mobile-first); no envíes un diseño solo para escritorio.

5. Formularios y validación

  • Define un esquema Zod por formulario/forma de datos; reutiliza el mismo esquema para la validación del cliente (a través de @hookform/resolvers/zod) y la validación del lado del servidor dentro de la Server Action — nunca confíes en la validación solo del cliente.
  • React Hook Form (useForm) maneja el estado del cliente; al enviar, llama a una Server Action, muestra los errores de campo del valor de retorno estructurado de la acción (no excepciones lanzadas que terminan en un error genérico).
  • Valida process.env con un esquema Zod al inicio (un lib/env.ts) para que la configuración faltante/incorrecta falle rápidamente en lugar de en el primer uso.

6. Base de datos (PostgreSQL + Drizzle)

  • El esquema reside en lib/db/schema.ts (o dividido por dominio), las migraciones se generan mediante drizzle-kit generate y se aplican mediante drizzle-kit migrate — nunca edites manualmente los archivos de migración generados.
  • Usa una conexión agrupada (ej. a través del pool del controlador o un proveedor como Neon/Supabase pooling) en contextos serverless/edge; no abras un nuevo cliente por solicitud sin agrupación.
  • Optimización de consultas y prevención de N+1: usa consultas relacionales de Drizzle (db.query.x.findMany({ with: {...} })) o joins explícitos en lugar de bucles y consultas por fila; selecciona solo las columnas que necesitas en lugar de recuperaciones de filas completas al estilo select *; pagina/limita cualquier consulta que pueda devolver un conjunto de resultados ilimitado.
  • Indexa las columnas utilizadas en WHERE/ORDER BY/joins; agrégalas en el esquema, no como una ocurrencia tardía.
  • Mantén una historia de copia de seguridad/restauración documentada para bases de datos de producción (instantáneas del proveedor administrado como mínimo) — menciona esto si la configuración del usuario no tiene ninguna.

7. Autenticación y seguridad

  • Better Auth para autenticación (sesiones, proveedores OAuth, email/contraseña según sea necesario); nunca implementes manualmente hash de contraseñas o tokens de sesión.
  • RBAC: modela roles/permisos explícitamente (una columna role más un pequeño helper de verificación de permisos), y aplica la autorización en la Server Action / capa de acceso a datos, no solo ocultando la UI — un botón oculto no es control de acceso.
  • Limita la tasa de puntos finales sensibles (auth, envíos de formularios, cualquier cosa costosa) — ej. a través de Upstash Redis o un limitador de token-bucket/sliding-window equivalente.
  • Establece encabezados de seguridad (a través de next.config.js headers o middleware): Content-Security-Policy, X-Frame-Options, Referrer-Policy, Permissions-Policy, Strict-Transport-Security.
  • Cookies: httpOnly, secure, sameSite: 'lax' (o 'strict' cuando sea factible) en todas las cookies de autenticación/sesión.
  • Valida cada entrada externa (datos de formulario, parámetros de consulta, payloads de webhook) con Zod en el límite antes de que toque la lógica empresarial o la base de datos.
  • Nunca registres secretos, tokens o cuerpos de solicitud completos que contengan credenciales.

8. SEO

  • Usa la API de Metadatos (generateMetadata / exportación de metadata estática) por ruta — título, descripción, Open Graph, tarjeta de Twitter.
  • Proporciona app/sitemap.ts y app/robots.ts generados a partir de datos de ruta reales, no una lista desactualizada codificada.
  • Establece URLs canónicas a través de alternates.canonical de metadatos, especialmente en cualquier ruta accesible a través de múltiples variantes de cadena de consulta.
  • Añade datos estructurados JSON-LD para tipos de contenido que se beneficien (artículos, productos, migas de pan, organización) usando una etiqueta script con type="application/ld+json".

9. Accesibilidad

  • HTML semántico primero (button, nav, main, header, label) — recurre a ARIA solo para llenar un vacío real que el HTML semántico no puede cubrir.
  • Todo accesible y operable solo con teclado; estados de enfoque visibles (no elimines los contornos de :focus-visible sin reemplazarlos).
  • Cada imagen tiene un alt significativo (alt="" vacío solo para imágenes genuinamente decorativas).
  • Cada entrada de formulario tiene una etiqueta <label> real asociada (no solo un placeholder).
  • Verifica el contraste de color contra WCAG AA como mínimo para texto y elementos interactivos.

10. Manejo de errores y estados de carga

Cada segmento de ruta que pueda fallar o tomar tiempo debe tener:

  • error.tsx — límite de error a nivel de segmento con una acción de reintento.
  • global-error.tsx — fallback de nivel superior para errores que error.tsx no puede capturar.
  • not-found.tsx — para 404s, incluyendo llamadas notFound() desde búsquedas de datos.
  • loading.tsx — fallback de Suspense; hazlo un esqueleto real que coincida con el diseño final, no un spinner vacío.

11. Testing

  • Vitest para pruebas unitarias (funciones puras, validación de esquemas, lógica de utilidades) y pruebas de componentes (React Testing Library) — colocalas como *.test.ts(x) o bajo __tests__/.
  • Playwright para flujos de extremo a extremo: autenticación, recorridos críticos del usuario, envíos de formularios. Ejecuta contra un despliegue de vista previa o una compilación local, no contra producción.
  • Las nuevas Server Actions y esquemas de validación deben enviarse con al menos una prueba básica; no dejes que la lógica empresarial crítica no se pruebe por defecto.

12. Monitoreo y logging

  • Sentry para seguimiento de errores tanto en cliente como en servidor (archivo de instrumentación + sentry.client.config / sentry.server.config), con mapas de origen cargados en el despliegue.
  • Logging estructurado (logs JSON con id de solicitud, ruta, id de usuario cuando estén disponibles) en lugar de console.log ad hoc.
  • Rastrea las Core Web Vitals en producción (Vercel Analytics o Sentry Performance) y configura monitoreo de disponibilidad en la URL desplegada.

13. DevOps

  • Git con commits convencionales y con alcance; rama main protegida.
  • CI de GitHub Actions en cada PR: instalar → lint → typecheck → pruebas unitarias → compilar (añade e2e para cambios más grandes).
  • Despliega en Vercel; cada PR obtiene un despliegue de vista previa antes de fusionar.
  • Variables de entorno gestionadas por entorno en Vercel, validadas al inicio mediante el esquema Zod de entorno de la §5.

14. Multimedia

  • Cloudinary para multimedia subida por el usuario/dinámica: sube a través de parámetros de subida firmados y emitidos por el servidor (nunca expongas el secreto de API del lado del cliente), y sirve a través de las URLs de transformación de Cloudinary en lugar de reimplementar el redimensionamiento.

15. Convenciones de trabajo para Claude

Cuando se te pida añadir una característica en un proyecto que use este stack:

  1. Verifica el esquema/acciones/componentes existentes antes de crear nuevos — extiende, no dupliques.
  2. Nuevos campos de BD → actualiza schema.ts, genera una migración, no edites SQL manualmente.
  3. Nuevo formulario → esquema Zod → formulario RHF → Server Action con revalidación del lado del servidor y una verificación de autorización.
  4. Nueva ruta → decide estática vs dinámica deliberadamente; añade loading.tsx/error.tsx si faltan; añade metadatos.
  5. Después de una mutación, revalida la ruta/etiqueta específica afectada — no revalides toda la aplicación de forma general.
  6. Ejecuta lint/typecheck mentalmente contra el modo estricto antes de presentar código; señala cualquier any, entrada no verificada o verificación de autorización faltante en lugar de enviarlo silenciosamente.
  7. Antes de introducir, reemplazar u omitir cualquier herramienta de la sección 0, pregunta al usuario con opciones (consulta la regla "Recomendado, no estricto" en la sección 0).

16. Archivo de reglas complementarias

  • AGENTS.md — la regla de flujo de trabajo del proyecto (Flujo Principal, Flujo de Características, aprobación ga

Skills relacionados