Solid, Vue y Svelte como islas
Los tres frameworks conviven en Astro bajo el mismo contrato de islas —las mismas directivas client, el mismo paso de props serializables, el mismo modelo de slots— pero por dentro son motores radicalmente distintos: Solid teje reactividad de grano fino sin árbol virtual y con JSX que colisiona con React; Vue trae componentes de fichero único con extensión propia y un ecosistema maduro; Svelte compila el componente y casi no envía runtime. Cómo se integra cada uno, en qué difieren su coste de hidratación y su reactividad, y qué criterio usar para elegir isla por isla.
Desde fuera, una isla de Solid, una de Vue y una de Svelte son idénticas: se colocan en una plantilla .astro, reciben props serializables, aceptan contenido anidado y se hidratan con las mismas directivas client:. El contrato de renderer que viste en la primera lección las iguala en la superficie. Por dentro, sin embargo, son tres cosmovisiones distintas de cómo un componente se vuelve interactivo, y esas diferencias —de reactividad, de peso, de coste de hidratación— son precisamente las que deberían guiar cuál eliges para cada isla. Aquí las miramos de frente.
- Reconocer que los tres frameworks comparten el mismo contrato de islas y difieren solo por dentro.
- Integrar Solid y entender su reactividad de grano fino sin árbol virtual, y su colisión de JSX.
- Integrar Vue con sus componentes de fichero único y su punto de entrada de aplicación.
- Integrar Svelte y captar por qué su compilador reduce el runtime enviado al cliente.
El mismo contrato, tres motores distintos
Añadir cualquiera de los tres es el mismo gesto —astro add solid, astro add vue o astro add svelte— y produce el mismo tipo de configuración: una integración que registra su renderer. A partir de ahí, todo lo que aprendiste sobre islas se aplica sin cambios. Las directivas client:load, client:idle, client:visible y client:only funcionan igual en los tres; las props deben ser serializables en los tres, porque todas cruzan la misma frontera servidor-cliente; y el contenido anidado de Astro se expone en cada uno a través de su propio mecanismo de slots.
import { defineConfig } from 'astro/config';
import solid from '@astrojs/solid-js';
import vue from '@astrojs/vue';
import svelte from '@astrojs/svelte';
export default defineConfig({
integrations: [solid(), vue(), svelte()],
});
El contenido anidado también se comporta igual en los tres: lo que escribes entre las etiquetas de la isla llega a través del mecanismo de slots de cada framework —children en Solid, slots con nombre en Vue y en Svelte— pero siempre como HTML renderizado por Astro, con la misma naturaleza inerte que ya conoces. Esa uniformidad es en sí misma valiosa, porque la destreza que adquieres con un framework en Astro se transfiere íntegra al siguiente: cambiar de motor no te obliga a reaprender Astro, solo a reaprender el interior de la pieza que metes dentro.
En la práctica, pocos proyectos necesitan los tres a la vez; lo común es elegir uno y usarlo para todas las islas. Pero saber que puedes mezclarlos —y a qué precio— es lo que convierte la elección en informada en lugar de supersticiosa, y es además la base de la lección siguiente, donde islas de frameworks distintos tendrán que compartir estado.
Lo que cambia no es cómo se enrolan ni cómo se hidratan, sino qué motor de reactividad viaja dentro de cada isla y cuánto pesa. Esa es la variable que de verdad decide, y para razonarla hay que abrir los tres.
Solid: reactividad de grano fino sin árbol virtual
Solid escribe con JSX, igual que React, pero su modelo es el opuesto. No hay árbol virtual ni reconciliación: un componente de Solid se ejecuta una sola vez para tender un grafo de reactividad, y a partir de ahí solo se actualiza el nodo exacto del DOM que depende de una señal que cambió. No se repinta el componente entero, se repinta el fragmento mínimo.
// Contador.jsx de Solid
import { createSignal } from 'solid-js';
export default function Contador() {
const [n, setN] = createSignal(0);
return <button onClick={() => setN(n() + 1)}>Valor: {n()}</button>;
}
Esa arquitectura tiene dos consecuencias directas para las islas. La primera es un runtime diminuto y una hidratación barata, porque no hay que reconstruir un árbol virtual en el cliente. La segunda es una advertencia práctica: como Solid usa .jsx y .tsx, colisiona con React y con Preact igual que ellos entre sí, y si conviven en un proyecto necesitas separarlos con include y exclude, tal como viste en la primera lección.
Para quien llega desde React, la sintaxis resulta casi idéntica y portar un componente sencillo es mecánico; lo que cambia no es la forma del código, sino el modelo por debajo. En Solid, las props son en sí mismas reactivas y desestructurarlas puede romper esa reactividad, un detalle que sorprende al recién llegado y que revela hasta qué punto la familiaridad de la sintaxis esconde un motor distinto. Como isla, esa diferencia se traduce en menos JavaScript trabajando en el navegador por cada interacción.
Vue: componentes de fichero único y ecosistema
Vue trae su propia extensión, el componente de fichero único .vue, que agrupa plantilla, lógica y estilos en un solo archivo. Al ser una extensión única, nunca colisiona con otro renderer: Astro sabe sin ambigüedad que un .vue es de Vue.
<!-- Contador.vue -->
<script setup>
import { ref } from 'vue';
const n = ref(0);
</script>
<template>
<button @click="n++">Valor: {{ n }}</button>
</template>
Su reactividad se apoya en proxies: ref y reactive envuelven los datos para observar cuándo se leen y se escriben. Para las islas, Vue aporta sobre todo ergonomía y un ecosistema maduro —gestión de estado con Pinia, una cultura de componentes muy asentada—. La integración @astrojs/vue ofrece además una opción appEntrypoint, un fichero donde registras plugins o componentes globales sobre la instancia de aplicación antes de que se hidraten tus islas, útil cuando varias comparten configuración común.
El fichero único aporta un detalle cómodo para las islas: su bloque de estilos encapsula la presentación por defecto, de modo que una isla de Vue viaja con su aspecto incluido, sin fugar reglas al resto de la página. A cambio, su runtime es más pesado que el de Solid o Svelte, y ese es precisamente el compromiso que Vue pide —ergonomía y ecosistema a cambio de algunos kilobytes más por isla— y que solo tú puedes valorar para tu caso.
Svelte: el compilador que casi no envía runtime
Svelte es el más distinto de los tres, porque no es tanto una librería en tiempo de ejecución como un compilador. Un componente .svelte se transforma en build en JavaScript imperativo que manipula el DOM directamente; apenas viaja un puñado de helpers, no un framework completo. El resultado son bundles minúsculos.
<!-- Contador.svelte con runas de Svelte 5 -->
<script>
let n = $state(0);
</script>
<button on:click={() => n++}>Valor: {n}</button>
Con las runas de Svelte 5 —$state, $derived, $effect— la reactividad es explícita y granular, pero el rasgo que importa para Astro sigue siendo el mismo: como la mayor parte del trabajo ocurre en compilación, la isla llega al cliente con muy poco código de framework que descargar y ejecutar. Igual que Vue, su extensión .svelte es única y no colisiona con nada.
El coste de esa compilación lo paga tu máquina en el build, no el visitante en su navegador, que es exactamente el reparto que Astro persigue en cada pieza: empujar el trabajo hacia el momento y el lugar donde nadie lo sufre. Por eso Svelte encaja tan naturalmente en el modelo de islas —su filosofía de mover cómputo a compilación rima con la de Astro de mover cómputo al servidor—, y por eso suele producir las islas más ligeras de los cuatro frameworks para una interactividad equivalente.
Solid
JSX y señales de grano fino sin árbol virtual. Runtime minúsculo e hidratación barata. Colisiona con React y Preact por compartir .jsx.
Vue
Fichero único .vue con plantilla, lógica y estilos. Reactividad por proxies y ecosistema maduro. Extensión propia, sin conflictos.
Svelte
Compilador que emite JavaScript imperativo y casi no envía runtime. Bundles minúsculos y runas explícitas. Extensión propia .svelte.
flowchart TD ISLA[contrato de isla comun] --> SOL[solid] ISLA --> VUE[vue] ISLA --> SVE[svelte] SOL --> SR[senales de grano fino sin arbol virtual] VUE --> VR[proxies y fichero unico vue] SVE --> SVR[compilador con runtime minimo] SR --> COSTE[coste de hidratacion y peso del bundle] VR --> COSTE SVR --> COSTE style ISLA fill:#89b4fa,color:#11111b style COSTE fill:#a6e3a1,color:#11111b
La pregunta útil no es cuál es el mejor framework, sino cuál conviene a esta isla en este proyecto. Si la isla es pequeña y el peso de JavaScript manda —un widget en una landing, un componente repetido en muchas páginas—, Solid y Svelte brillan por su runtime mínimo. Si tu equipo ya piensa en Vue o dependes de su ecosistema, la ergonomía del fichero único y la familiaridad valen más que unos kilobytes. Y como cada isla carga su framework solo dentro de sí misma, la elección es local y reversible: nada te obliga a un único framework para todo el sitio. Elige por isla, no por lealtad.
Cambiar de framework no cambia las leyes de la hidratación. En los tres, las props que pasas a una isla hidratada deben ser serializables, porque cruzan la misma frontera servidor-cliente; y el contenido anidado que envías desde Astro se expone a través del mecanismo de slots de cada framework, pero llega igual de inerte en todos. Lo que aprendiste con React sobre datos que cruzan y comportamiento que no, se aplica sin excepción a Solid, Vue y Svelte.
Hay una directiva que sí distingue entre frameworks: client:only. Como omite el render de servidor, Astro no puede deducir de qué motor es el componente observando su salida, así que debes decírselo con una cadena —client:only="react", client:only="vue", client:only="svelte"—. Es el único punto donde la elección de framework asoma dentro de la propia directiva; en un proyecto con varios enrolados, olvidar ese nombre es una fuente habitual de fallos silenciosos al hidratar.
Ver a Solid, Vue y Svelte alineados bajo el mismo contrato de islas enseña algo que ninguno de ellos enseña por separado: que la elección de framework, tan cargada de identidad en la cultura del desarrollo front, es en realidad una decisión de implementación local, no de arquitectura. La arquitectura —cuándo corre el código, dónde vive el cómputo, cuánto JavaScript recibe el usuario, cómo se aísla lo interactivo de lo estático— la fija Astro con su modelo de islas, y es la misma sea cual sea el framework que metas dentro. Lo que el framework decide es más estrecho de lo que su marketing sugiere: cómo se expresa la reactividad y cuánto runtime cuesta esa expresividad. Solid apuesta por un grafo de dependencias de grano fino; Svelte por mover el trabajo al compilador; Vue por proxies y ergonomía; React por un árbol virtual reconciliado. Son cuatro respuestas a la misma pregunta interna, y todas se acoplan a Astro por la misma interfaz de dos entrypoints. Interiorizar esto libera de un debate estéril. Deja de importar cuál framework es objetivamente superior, porque la pregunta está mal planteada: no hay un ganador, hay compromisos —peso contra ergonomía, compilación contra flexibilidad, grano fino contra ecosistema— y el compromiso correcto depende de la isla concreta y del equipo concreto. Astro convierte esa elección de un juramento de por vida en una decisión de ingeniería que tomas de nuevo en cada componente, con datos a la vista: cuánto pesa el bundle, cuánto cuesta hidratar, qué librerías necesitas. La madurez que este nivel pide no es dominar un framework hasta la identidad, sino cultivar la indiferencia productiva de quien ve cuatro herramientas, conoce el compromiso de cada una y escoge sin apego la que resuelve el problema que tiene delante. El framework es intercambiable; el juicio para elegirlo, no.
- Enrola Solid, Vue y Svelte en un mismo proyecto y escribe el mismo contador en los tres, cada uno como isla con
client:load. - Construye e inspecciona la red: compara el peso del JavaScript que descarga cada isla y ordena los tres frameworks por coste.
- Añade Solid junto a React sin acotar y provoca la colisión de
.jsx; resuélvela conincludey explica por qué Vue y Svelte no la sufren. - Pasa una prop no serializable a una isla de Vue y observa el fallo; confirma que el límite es idéntico al de React y razona por qué depende de la frontera, no del framework.