Construimos el Mismo Dashboard en SolidJS y React: La Verdad sobre Signals
El dashboard de análisis de tu cliente se congela durante 340 milisegundos cada vez que un usuario cambia el rango de fechas en un gráfico con 3,000 puntos de datos. El reconciliador de React está procesando nodos de VDOM, los hooks se disparan en cascada, y tu bundle acaba de superar los 180 kB comprimido. El trimestre pasado reconstruimos exactamente este dashboard de producción—autenticación, actualizaciones WebSocket en tiempo real, formularios complejos de varios pasos, módulo de gráficos—en SolidJS y React, instrumentalizamos cada renderizado, registramos cada byte del bundle, y ejecutamos los mismos flujos de usuario en ambas versiones. La brecha de rendimiento fue más amplia de lo que esperábamos, pero no donde pensábamos.
Los resultados nos sorprendieron. No porque un framework "ganara"—sino porque los tradeoffs eran mucho más matizados de lo que sugiere el discurso de Twitter. Algunas cosas las esperábamos. Algunas cosas nos sorprendieron completamente. Esto es lo que realmente aprendimos.
Tabla de Contenidos
- La App que Construimos
- Signals vs Hooks: Un Cambio de Modelo Mental
- Comparación de Tamaño del Bundle
- Benchmarks de Rendimiento de Renderizado
- Experiencia del Desarrollador y Ecosistema
- Tradeoffs de Producción que Realmente Importan
- Cuándo Elegir SolidJS sobre React
- Comparación de Código: Patrones Reales
- Preguntas Frecuentes

La App que Construimos
La aplicación es un dashboard de análisis en tiempo real para un cliente de e-commerce. Aquí está lo que incluye:
- Flujo de autenticación con tokens JWT y lógica de renovación
- Dashboard con 6 paneles de widgets, cada uno extrayendo datos de diferentes endpoints de API
- Feed de órdenes en tiempo real usando conexiones WebSocket
- Gráficos interactivos que renderizan 5,000+ puntos de datos (usando una librería de gráficos)
- Formularios de filtro complejos con dropdowns dependientes y selectores de rango de fechas
- Panel de configuración de administrador con gestión de estado anidada
- Diseño responsivo con navegación de barra lateral
Ambas versiones se conectan a la misma API de backend. Ambas usan TypeScript. Ambas usan Vite como herramienta de compilación. Mantuvimos las dependencias de terceros lo más similares posible—la misma librería de gráficos (Chart.js), el mismo cliente HTTP (ky), el mismo wrapper de WebSocket.
La versión de React usa React 19 con hooks. La versión de SolidJS usa Solid 1.9. No usamos meta-frameworks (sin Next.js, sin SolidStart) porque queremos aislar las diferencias del framework sin que el enrutamiento y SSR confundan la comparación.
Signals vs Hooks: Un Cambio de Modelo Mental
Este es el grande. Y honestamente, le tomó a nuestro equipo aproximadamente una semana dejar de escribir código en forma de React en SolidJS.
Cómo Funcionan los Hooks de React
Ya sabes esto, pero vale la pena declararlo explícitamente para la comparación. El modelo de React es: cuando el estado cambia, la función del componente se re-ejecuta. La función completa. Cada useState, cada useMemo, cada useCallback—todos son mecanismos para trabajar alrededor del hecho de que toda la función se re-ejecuta.
// React: Esta función completa se re-ejecuta en cada cambio de estado
function OrderFeed() {
const [orders, setOrders] = useState([]);
const [filter, setFilter] = useState('all');
// Esto se recalcula en cada renderizado a menos que lo memoricemos
const filteredOrders = useMemo(() =>
orders.filter(o => filter === 'all' || o.status === filter),
[orders, filter]
);
// Esta ref se recrea conceptualmente en cada renderizado
const handleNewOrder = useCallback((order) => {
setOrders(prev => [order, ...prev]);
}, []);
useEffect(() => {
const ws = connectWebSocket(handleNewOrder);
return () => ws.close();
}, [handleNewOrder]);
return <OrderList orders={filteredOrders} />;
}
Cómo Funcionan los Signals de Solid
El modelo de Solid es fundamentalmente diferente. La función del componente se ejecuta una vez. Después de eso, solo las expresiones específicas que leen un signal se re-ejecutan cuando ese signal cambia. No hay virtual DOM diff. No hay reconciliación. El gráfico reactivo rastrea exactamente qué nodos DOM dependen de qué signals.
// Solid: Esta función se ejecuta UNA VEZ
function OrderFeed() {
const [orders, setOrders] = createSignal([]);
const [filter, setFilter] = createSignal('all');
// Esto se rastrea automáticamente—sin necesidad de array de dependencias
const filteredOrders = createMemo(() =>
orders().filter(o => filter() === 'all' || o.status === filter())
);
// No se necesita useCallback—este closure es estable
const handleNewOrder = (order) => {
setOrders(prev => [order, ...prev]);
};
// onMount en lugar de useEffect con deps vacías
onMount(() => {
const ws = connectWebSocket(handleNewOrder);
onCleanup(() => ws.close());
});
return <OrderList orders={filteredOrders()} />;
}
Lo que Esto Significa en la Práctica
La versión de Solid no tiene arrays de dependencias. Sin useCallback. Sin useMemo para estado derivado (aunque createMemo existe para cálculos costosos—la diferencia es que es opt-in para rendimiento, no requerido para corrección).
Aquí está lo que realmente nos mordió durante el desarrollo:
La desestructuración de props mata la reactividad en Solid. Teníamos un desarrollador junior desestructurar props en un componente Solid y gastamos 45 minutos depurando por qué las actualizaciones no se propagaban. En React, la desestructuración está bien porque toda la función se re-ejecuta. En Solid, necesitas acceder a
props.valuedentro del JSX o un scope rastreado.Los retornos tempranos son complicados en Solid. No puedes hacer
if (!data()) return <Loading />en la parte superior de un componente Solid de la forma en que lo harías en React. La función del componente se ejecuta una sola vez, así que ese condicional nunca se reevaluaría. Necesitas<Show when={data()}>en su lugar.Sin bugs de closure obsoleto. Esta fue la gran victoria. En nuestra versión de React, tuvimos tres bugs de closure obsoleto en la primera semana relacionados con manejadores WebSocket capturando estado antiguo. La versión de Solid tenía cero, porque los signals siempre se leen en el momento del acceso, no capturados en un closure.
Comparación de Tamaño del Bundle
Medimos ambas compilaciones de producción con exactamente la misma configuración de Vite, compresión gzip, y estrategia de code splitting.
| Métrica | React 19 | SolidJS 1.9 | Diferencia |
|---|---|---|---|
| Runtime del framework | 44.2 KB (gzip) | 7.1 KB (gzip) | -84% |
| Bundle inicial total | 127.8 KB | 89.3 KB | -30% |
| App total (todos los chunks) | 312.4 KB | 274.1 KB | -12% |
| Primer chunk (ruta crítica) | 68.4 KB | 41.2 KB | -40% |
| Número de chunks | 14 | 14 | Igual |
El runtime de Solid es dramáticamente más pequeño. Eso no es novedad—Ryan Carniato ha hablado sobre esto extensamente. Pero lo que nos sorprendió fue que la diferencia total del tamaño de la app se estrechó significativamente una vez que agregas código de aplicación real, librerías de terceros, y assets.
El runtime del framework importa más para la carga inicial. Y con 7.1 KB comprimido, Solid básicamente desaparece en el ruido. Los 44 KB de React son notables, especialmente en conexiones móviles.
Tree Shaking
Solid hace tree-shaking mejor que React. Los primitivos de Solid no utilizados se eliminan completamente. Con React, el reconciliador y la arquitectura de fiber se envían independientemente de que uses todas sus características o no. Confirmamos esto construyendo una página mínima en ambas—el piso de Solid es más bajo.

Benchmarks de Rendimiento de Renderizado
Ejecutamos benchmarks estructurados usando perfiles de rendimiento de Chrome DevTools, Lighthouse, e instrumentación de timing personalizada. Todas las pruebas en un MacBook Pro M2 con CPU throttling establecido en ralentización de 4x para simular dispositivos de rango medio.
Renderizado de Gráficos (5,000 puntos de datos)
| Métrica | React 19 | SolidJS 1.9 |
|---|---|---|
| Renderizado inicial | 142ms | 89ms |
| Re-renderizado en cambio de filtro | 67ms | 23ms |
| Memoria durante renderizado | 18.4 MB | 11.2 MB |
| Nodos DOM creados | 5,847 | 5,812 |
Solid fue consistentemente más rápido en re-renderizados porque no difiere un árbol de DOM virtual. Cuando un signal de filtro cambia, solo las expresiones que leen ese signal se actualizan. Las mejoras del compilador de React 19 ayudaron—la misma prueba en React 18 fue 95ms para re-renderizados—pero Solid aún tenía una ventaja clara.
Feed de Órdenes en Tiempo Real (100 actualizaciones/segundo)
Esto es donde las cosas se pusieron realmente interesantes. Presionamos 100 mensajes de WebSocket por segundo al feed de órdenes.
| Métrica | React 19 | SolidJS 1.9 |
|---|---|---|
| Caídas de fotogramas (por 10s) | 12 | 2 |
| Tiempo de pintura promedio | 8.3ms | 3.1ms |
| Tiempo de pintura máximo | 34ms | 11ms |
| Uso de CPU (promedio) | 24% | 9% |
Solid absolutamente aplastó este benchmark. Las actualizaciones de alta frecuencia son donde la reactividad de grano fino paga los mayores dividendos. React estaba agrupando actualizaciones (lo cual es bueno), pero aún diferenciaba más DOM del necesario en cada agrupamiento.
Debemos notar: useTransition de React 19 y el agrupamiento automático hicieron esto mucho mejor de lo que habría sido React 18. Y para la mayoría de las apps del mundo real, no estás presionando 100 actualizaciones por segundo. A 10 actualizaciones/segundo, ambos frameworks eran suaves.
Formulario Complejo con 40 Campos
| Métrica | React 19 | SolidJS 1.9 |
|---|---|---|
| Lag de entrada de tecla | 2-4ms | <1ms |
| Renderizado de envío de formulario | 28ms | 12ms |
| Re-renderizados de componentes por tecla | 3-8 | 1 |
En React, escribir en un campo haría que los componentes padres se re-renderizaran a menos que memorizáramos cuidadosamente todo. En Solid, escribir en un campo literalmente solo actualiza el nodo de texto DOM de ese campo. Nada más se re-ejecuta.
Experiencia del Desarrollador y Ecosistema
El rendimiento no lo es todo. Tienes que construir realmente la cosa, depurarla, contratar para ella, y mantenerla.
Tamaño del Ecosistema (a principios de 2026)
| Factor | React | SolidJS |
|---|---|---|
| Descargas semanales en npm | ~28M | ~85K |
| Estrellas en GitHub | 233K+ | 33K+ |
| Preguntas en Stack Overflow | 470K+ | ~2K |
| Librerías de componentes UI | 50+ opciones maduras | 5-8 opciones |
| Publicaciones de empleo (LinkedIn US) | ~45,000 | ~200 |
| Meta-framework | Next.js (maduro) | SolidStart (beta) |
Este es el elefante en la habitación. El ecosistema de React es órdenes de magnitud más grande. Cuando necesitábamos un selector de rango de fechas para Solid, tuvimos que portar uno de React o escribir el nuestro. En React, teníamos 15 opciones para elegir.
Usamos Kobalte para primitivos UI accesibles en Solid, y es genuinamente bueno. Pero no es Radix UI en términos de cobertura de componentes.
Depuración
React DevTools es maduro, bien mantenido, y algo que todo desarrollador frontend conoce. Solid tiene su propia extensión de DevTools, y es decente—puedes inspeccionar el gráfico de signals, que es realmente más útil para rastrear bugs de reactividad que la vista del árbol de componentes de React. Pero está menos pulido.
Soporte de TypeScript
Ambos son excelentes. El soporte de TypeScript de Solid es en realidad ligeramente mejor para JSX porque el compilador maneja más en el momento de construcción. Tuvimos menos acrobacias de tipos en la base de código de Solid.
Tradeoffs de Producción que Realmente Importan
Después de construir ambas versiones e implementar la versión de Solid en staging (el cliente finalmente eligió React para producción—más sobre eso abajo), aquí están los tradeoffs que realmente importaban:
Contratación
Nuestro cliente tiene un equipo de 8 desarrolladores frontend. Todos conocen React. Ninguno había usado Solid. Estimación del tiempo de capacitación: 2-3 semanas para competencia, 2-3 meses para dominio. Ese es un costo real. Este es el factor más importante en la mayoría de las decisiones de producción, y es por qué típicamente recomendamos React o frameworks como Next.js para equipos que necesitan contratar frecuentemente.
Compatibilidad de Librerías de Terceros
Tuvimos que escribir wrappers personalizados para tres librerías que tenían integraciones específicas de React. Esto agregó aproximadamente 20 horas de tiempo de desarrollo. En un proyecto React, esas horas no existen.
Renderizado del Lado del Servidor
SolidStart es promisorio pero aún estaba en beta durante nuestro proyecto. Next.js está bien probado en batalla. Para proyectos donde necesitamos SSR de grado de producción con todos los extras, aún recurrimos a desarrollo de Next.js o Astro dependiendo del modelo de contenido.
Rendimiento Donde Importa
Aquí está la verdad honesta: para este dashboard en particular, ambos frameworks se desempeñaron lo suficientemente bien para producción. La versión de Solid fue mediblemente más rápida, pero la versión de React nunca fue lenta. Los usuarios no notarían la diferencia en la mayoría de las interacciones.
La excepción fue el feed en tiempo real con altas frecuencias de actualización. Si tu app tiene un caso de uso como ese, la ventaja de rendimiento de Solid es significativa, no solo jactancia de benchmark.
Cuándo Elegir SolidJS sobre React
Después de este experimento, aquí está nuestro marco honesto para la decisión:
Elige SolidJS cuando:
- Tu app tiene actualizaciones reactivas de alta frecuencia (dashboards, plataformas de trading, colaboración en tiempo real)
- El tamaño del bundle es crítico (widgets incrustados, micro-frontends, móvil primero)
- Tu equipo es pequeño y dispuesto a invertir en aprender un nuevo paradigma
- Quieres reactividad de grano fino sin luchar contra el framework
- Estás construyendo algo nuevo y no necesitas un ecosistema masivo de librerías de componentes
Elige React cuando:
- Tu equipo ya conoce React (esto solo es usualmente decisivo)
- Necesitas un meta-framework maduro (Next.js, Remix)
- La disponibilidad de librerías de terceros es importante
- Estás contratando y necesitas un gran grupo de talentos
- Los requisitos de rendimiento de tu app son típicos (no extremos)
Para nuestros proyectos de desarrollo de CMS sin cabeza, React aún domina porque las integraciones de CMS (Sanity, Contentful, Storyblok) tienen SDKs de React de primera clase. El soporte de Solid existe pero a menudo es mantenido por la comunidad.
Comparación de Código: Patrones Reales
Miremos algunos patrones reales del proyecto lado a lado.
Extracción de Datos con Estados de Carga
React:
function Dashboard() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchDashboardData()
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) return <Skeleton />;
if (error) return <ErrorBanner error={error} />;
return <DashboardGrid data={data} />;
}
SolidJS:
function Dashboard() {
const [data] = createResource(fetchDashboardData);
return (
<Suspense fallback={<Skeleton />}>
<ErrorBoundary fallback={(err) => <ErrorBanner error={err} />}>
<DashboardGrid data={data()} />
</ErrorBoundary>
</Suspense>
);
}
createResource de Solid con Suspense es genuinamente elegante. React también tiene Suspense (y ha mejorado en React 19), pero la versión de Solid se sentía más natural para trabajar. Menos boilerplate, menos variables de estado para gestionar.
Renderizado Condicional
React:
{user ? (
<Profile user={user} />
) : (
<LoginPrompt />
)}
SolidJS:
<Show when={user()} fallback={<LoginPrompt />}>
{(u) => <Profile user={u()} />}
</Show>
El componente <Show> de Solid existe porque los ternarios no funcionan igual cuando la función del componente se ejecuta una sola vez. Tomó acostumbrarse, pero el patrón de callback te da una referencia estrechada y no nula que es agradable para TypeScript.
Renderizado de Listas
React:
{orders.map(order => (
<OrderRow key={order.id} order={order} />
))}
SolidJS:
<For each={orders()}>
{(order) => <OrderRow order={order} />}
</For>
El <For> de Solid no necesita keys porque rastrea elementos del array por referencia. Cuando un elemento se mueve en el array, Solid mueve el nodo DOM actual. React desmontraría y remontraría. Es por eso que el rendimiento de listas de Solid es tan bueno.
Preguntas Frecuentes
¿Es SolidJS listo para producción en 2026? Sí. Solid 1.x ha sido estable durante más de dos años. Empresas como Cloudflare y Samsung lo han usado en producción. La librería central es madura y bien probada. El ecosistema alrededor (SolidStart, librerías de componentes) es más pequeño que el de React pero está creciendo constantemente. La pregunta no es si Solid está listo—es si tu equipo y requisitos del proyecto se alinean con su tamaño de ecosistema.
¿Puedo migrar de React a SolidJS incrementalmente? No fácilmente. A pesar de la sintaxis JSX similar, los modelos de runtime son fundamentalmente diferentes. No puedes incrustar componentes de Solid dentro de una app React (o viceversa) sin límites de iframe o web component. Una migración sería esencialmente una reescritura. Si la estás considerando, comienza con una nueva característica aislada o micro-frontend en lugar de intentar convertir código React existente.
¿SolidJS admite renderizado del lado del servidor? Sí. SolidStart proporciona SSR, streaming, y funciones de servidor. Es funcional y está mejorando rápidamente, pero a principios de 2026, aún es menos maduro que Next.js o Remix. Para proyectos intensivos en SSR, aún recomendaríamos evaluar Next.js o Astro dependiendo de tus necesidades de contenido.
¿Cómo se compara el compilador de React 19 con el enfoque de Solid? El compilador de React 19 (anteriormente React Forget) memoriza automáticamente componentes para reducir re-renderizados innecesarios. Es una mejora significativa. Pero aún está trabajando dentro del modelo de React de re-ejecutar funciones de componentes y diferenciar un DOM virtual. Solid omite ambos pasos completamente. El compilador hace React más rápido, pero no cambia la arquitectura fundamental. En nuestros benchmarks, React 19 con el compilador fue aproximadamente 30% más rápido que React 18, pero aún más lento que Solid en escenarios intensivos en actualizaciones.
¿Qué hay de Preact Signals como punto medio?
Preact Signals (y el adaptador @preact/signals-react) traen reactividad similar a signals al ecosistema de React. Es un enfoque interesante, pero está luchando contra el modelo central de React en lugar de trabajar con él. Lo probamos brevemente y encontramos casos extremos con Suspense y características concurrentes. Si quieres signals, Solid te da la experiencia completa sin el desajuste de impedancia.
¿Es SolidJS más difícil de aprender que React?
Si ya conoces React, la API de Solid te verá familiar—JSX similar, patrones similares. La parte difícil es desaprender el modelo mental de React. Buscarás patrones de useEffect que no existen. Desestructurarás props y romperás la reactividad. Intentarás retornos tempranos y te preguntarás por qué no funcionan. Presupuesta aproximadamente 1-2 semanas para que un desarrollador experimentado de React sea productivo en Solid, y otro mes o dos para dejar de escribir Solid con sabor a React.
¿Qué framework tiene mejor soporte de TypeScript?
Ambos tienen excelente soporte de TypeScript. Solid tiene una ligera ventaja porque su compilador puede proporcionar tipos más estrechos en ciertos patrones (como el callback en <Show>), y no necesitas el mismo volumen de parámetros de tipo genéricos que a veces requieren hooks de React complejos. Pero honestamente, ambos son excelentes. Esto no debería ser un factor decisivo.
¿Debería usar SolidJS para mi próximo proyecto? Depende de tus restricciones. Si eres un equipo pequeño construyendo algo sensible al rendimiento y estás dispuesto a invertir en curva de aprendizaje y trabajar alrededor de un ecosistema más pequeño, Solid es una opción genuinamente excelente. Si necesitas contratar desarrolladores de React, usar librerías de componentes establecidas, o necesitas un meta-framework probado en batalla para producción, React es la apuesta más segura. No hay una respuesta universal—solo la respuesta correcta para tu situación específica. Si quieres hablar a través de la decisión para tu proyecto, contáctanos y podemos ayudarte a evaluar los tradeoffs.