Stack del frontend: qué dice el estándar, qué corre el repo, qué usamos
Cuarta investigación. Versiones verificadas contra el registro de npm el 2026-08-30 y contra los trece
package.jsondel monorepo — no contra el apéndice del estándar, que está vencido.
1. El apéndice del estándar lleva dos majors de retraso
SV_Standard_Frontend Apéndice A se titula «Q2 2026» y él mismo exige revisión
trimestral. Estamos en Q3:
| Paquete | Dice el apéndice | Hay en npm | Corre el repo |
|---|---|---|---|
| React | ^19.2.0 |
19.2.8 | 19.2.8 ✅ |
| Vite | ^6.0.0 |
8.2.2 | 8.0–8.1 |
| Next.js | 15 | 16.3.3 | 16.3.3 |
| Tailwind | ^4.0.0 |
4.3.3 | 4.3.3 ✅ |
| TanStack Query | ^5.60.0 |
5.102.8 | 5.102 ✅ |
| Zod | ^3.24.0 |
4.5.4 | 4.4–4.5 |
@hookform/resolvers |
^3.10.0 |
5.9.1 | 5.2–5.9 |
| TypeScript | ^5.7.0 |
7.0.2 | 5.x–6.0.3 |
| Vitest | ^2.1.0 |
4.1.11 | 4.x |
Regla que se aplica: el apéndice se trata como orientación histórica; la referencia viva es lo que corre el repo. Nacer con Vite 6 sería nacer con dos majors de retraso para cumplir un documento vencido.
2. El hallazgo que decide una arquitectura
El estándar manda React Hook Form + Zod, sin excepciones (§6). Investigando salieron
incidencias abiertas de que Zod 4 rompe con zodResolver: el ZodError se lanza en
vez de capturarse, y el formulario revienta con una excepción sin manejar.
(react-hook-form #12816 ·
#13047)
Eso empujaba a cambiar a TanStack Form, que soporta Standard Schema de forma nativa y valida Zod 4 sin adaptador.
Pero el repo demuestra lo contrario. Nueve de trece frontends corren RHF + Zod 4 en
producción, y todos comparten un detalle: @hookform/resolvers v5. Las incidencias
son de resolvers v3 y v4.
| Frontend | RHF | Zod | resolvers |
|---|---|---|---|
| gastro/marketing-site | 7.86 | 4.5.4 | 5.9.1 |
| gastro/public-menu | 7.76 | 4.5.2 | 5.2.2 |
| travel/admin-panel | 7.80 | 4.4.3 | 5.4.0 |
| operator/frontend | 7.80 | 4.4.3 | 5.4.0 |
Decisión: RHF + Zod 4 + resolvers ≥5.9. Sin desviarse del estándar y sin adoptar una librería de formularios nueva que nadie más del monorepo conoce. Es exactamente el tipo de decisión que una búsqueda superficial habría cambiado sin necesidad.
3. TypeScript 7 existe y es 10× más rápido — y aun así no lo adoptamos
TypeScript 7.0 llegó a disponibilidad general el 8 de julio de 2026: compilador reescrito de forma nativa en Go, 8× a 12× más rápido. Comprobar tipos de VS Code bajó de 125,7 s a 10,6 s. (InfoQ · The Register)
Y aun así muebles nace con TypeScript 6.0.3, por dos razones:
- TS 7 sale sin API programática estable — se espera en 7.1 — y por eso el herramental de Vue, Angular y Svelte todavía está esperando. React sufre menos, pero «sufre menos» no es «está probado».
- Mi propio
AGENTS.mddice que desviarse del stack exige ADR. Adoptar un major de compilador que ningún otro workspace usa convertiría a muebles en un segundo estándar dentro del monorepo, decidido por una vertical que ni siquiera ha validado su hipótesis.
Queda como propuesta para el monorepo, no como decisión de esta vertical. Y muebles es el piloto natural cuando se tome: es la única sin código heredado.
4. Lo demás que cambió y sí adoptamos
El compilador de React es estable en Next 16. Memoiza automáticamente y elimina la
mayoría de los useMemo y useCallback escritos a mano. No viene activado por defecto;
se enciende con reactCompiler.
(Next.js 16)
Tailwind v4.3 con configuración en CSS. El archivo JavaScript ya no hace falta: los
tokens viven en @theme dentro del CSS, sobre un motor nuevo en Rust (Lightning CSS) que
baja las reconstrucciones completas de 3,5 s a menos de 100 ms. Encaja perfecto con
nuestro sistema de marca: las paletas curadas se inyectan como variables CSS y el @theme
las consume.
(Tailwind ·
LogRocket)
5. Lo que el estándar exige y el repo casi no usa
Medido sobre los trece frontends. Aquí es donde muebles puede nacer mejor que el resto:
| Herramienta | Exigido por | Adopción | Muebles |
|---|---|---|---|
| ESLint | §1 | 10/13 | ✅ |
| Vitest | §10 | 7/13 | ✅ |
| Playwright | §10 | 5/13 | ✅ |
| MSW | §10 | 3/13 | ✅ |
| nuqs | §5 | 3/13 | ✅ el filtro del catálogo vive en la URL o no se comparte |
| Storybook | §1 | 3/13 | ✅ el catálogo es un design system |
| Radix UI | §1 | 2/13 | ✅ el selector de variantes necesita teclado resuelto |
| Prettier | §1 | 2/13 | ✅ |
| axe-core | §11 | 1/13 | ✅ WCAG 2.2 AA es el mínimo del estándar |
| Cliente desde OpenAPI | §4 | 2/13 | ✅ ver abajo |
El cliente HTTP se genera, no se escribe
El estándar dice «cliente HTTP generado desde OpenAPI. Cero código manual de fetching» y solo 2 de 13 lo cumplen. Para muebles no es opcional: el contrato del catálogo —producto, variantes, tipos de opción, medidas, materiales, financiación— es el payload más grande del monorepo, y ya existe generado y con gate de deriva en CI. Escribirlo a mano en TypeScript garantiza que se desincronice.
6. Stack final
Showroom público (frontend/public-showroom) — Next.js 16 App Router. Se abre desde
WhatsApp: SEO, datos estructurados y primer render pesan.
Panel (frontend/admin-panel) — Vite 8 SPA. Va tras login, a Google no le importa.
Común a los dos:
React 19.2 · TypeScript 6.0.3 · Tailwind 4.3 (@theme en CSS)
TanStack Query 5.102 · Zustand 5 · nuqs 2.10
React Hook Form 7.87 + Zod 4.5 + @hookform/resolvers 5.9
Radix UI · Vitest 4 + Testing Library + MSW · Playwright 1.62
Storybook · ESLint + Prettier · axe-core
Cliente HTTP generado desde docs/03_REFERENCE/openapi.json
Arquitectura: FSD + Atomic Design, el árbol del §2.1 del estándar, con dependencias en
una sola dirección — shared → design-system → entities → features → widgets → pages → app.
Y la regla de purificación: si un componente sabe qué es una «variante», sale del
design-system.