Signals en frameworks
El mismo átomo, cinco dialectos: Solid, Angular, Preact Signals, Vue ref y Svelte 5 runes implementan el idéntico modelo con distinta sintaxis. Acceso por función, por .value o por runes de compilador; la convergencia de todo el ecosistema.
Si has entendido las cuatro lecciones anteriores, ya sabes usar los cinco frameworks que dominan 2026, aunque no lo parezca. Solid, Angular, Preact, Vue y Svelte 5 convergieron en el mismo modelo de signals; lo único que cambia entre ellos es la superficie: dónde pones los paréntesis, si escribes .value o si dejas que un compilador lo haga por ti. Esta lección traduce un único ejemplo a los cinco dialectos para que veas, con tus propios ojos, que debajo late siempre el mismo corazón. Aprender el modelo, no la sintaxis, es lo que te vuelve portátil.
- Reconocer el mismo modelo bajo Solid, Angular, Preact, Vue y Svelte 5.
- Comparar las tres formas de acceso: llamada a función,
.valuey runes de compilador. - Entender por qué el ecosistema entero convergió en signals.
- Traducir un mismo contador derivado entre los cinco dialectos.
El mismo modelo, cinco dialectos
Solid
El pionero moderno. createSignal devuelve un par getter/setter, createMemo es el computed y createEffect el efecto. Reactividad fina sin DOM virtual.
Angular
Desde la v16 trae signal(), computed() y effect() en el núcleo. Reemplaza buena parte de Zone.js y acerca Angular al grano fino.
Preact Signals
Librería aparte que añade signal(), computed() y effect(), con acceso por .value y una integración que evita re-renders del componente.
Vue
ref() es el signal, computed() la derivación y watchEffect() el efecto. La reactividad de Vue fue signals antes de que el nombre se popularizara.
Falta el quinto, que merece párrafo aparte por ser el más distinto en la forma: Svelte 5 y sus runes. Donde los otros son librerías en tiempo de ejecución, Svelte es un compilador, y eso le permite una sintaxis que parece no tener signals en absoluto.
Cómo se escribe en cada uno
El mismo contador con su doble derivado, cinco veces. Fíjate en que la estructura —un estado, un derivado, una lectura— es idéntica; solo cambia la ortografía:
// Solid: acceso por llamada a funcion
const [contar, setContar] = createSignal(0);
const doble = createMemo(() => contar() * 2);
setContar(contar() + 1);
console.log(doble());
// Angular: acceso por llamada, escritura por set o update
const contar = signal(0);
const doble = computed(() => contar() * 2);
contar.set(contar() + 1);
console.log(doble());
// Preact Signals: acceso por .value
const contar = signal(0);
const doble = computed(() => contar.value * 2);
contar.value += 1;
console.log(doble.value);
// Vue: ref y computed, acceso por .value en el script
const contar = ref(0);
const doble = computed(() => contar.value * 2);
contar.value += 1;
console.log(doble.value);
<!-- Svelte 5: runes; el compilador inserta el rastreo por ti -->
<script>
let contar = $state(0);
let doble = $derived(contar * 2);
function sumar() { contar += 1; }
</script>
En Svelte 5 escribes contar += 1 como si fuera una variable normal, sin getter ni .value. La reactividad no ha desaparecido: el compilador reescribe ese código en tiempo de build e inserta por ti las llamadas a signals que los demás escriben a mano. Es el mismo grafo de dependencias de siempre, solo que generado por la herramienta en lugar de por tus dedos. Runes como $state y $derived no son funciones de ejecución, sino señales para el compilador.
Acceso: función, .value o compilador
Las diferencias de sintaxis se reducen a una sola pregunta: cómo se intercepta la lectura para poder rastrearla. Hay tres respuestas, y cada framework eligió una.
| Framework | Estado | Derivado | Lectura |
|---|---|---|---|
| Solid | createSignal |
createMemo |
contar() |
| Angular | signal |
computed |
contar() |
| Preact | signal |
computed |
contar.value |
| Vue | ref |
computed |
contar.value |
| Svelte 5 | $state |
$derived |
contar |
La llamada a función —Solid, Angular— es explícita: los paréntesis marcan el punto de rastreo. El .value —Preact, Vue— usa un getter oculto tras una propiedad. Y las runes —Svelte— trasladan el trabajo al compilador, logrando la sintaxis más limpia a cambio de necesitar un paso de build. Tres caminos hacia la misma meta: ejecutar código en el instante de la lectura.
La escritura sigue la misma lógica de fachadas: Solid llama a setContar, Angular a contar.set, Preact y Vue mutan contar.value, y Svelte deja que un contar += 1 de aspecto trivial sea reescrito por el compilador. Detrás de cada gesto ocurre lo mismo —comparar con la igualdad, y si cambió, notificar—, pero la ortografía difiere lo justo para que un principiante crea que son mundos distintos cuando son el mismo mundo con cinco acentos.
El sexto dialecto que los unirá
Hay un sexto dialecto en camino, y es el que podría volver innecesario elegir: el del estándar de TC39. El mismo contador, escrito con los primitivos del lenguaje, no pertenece a ningún framework y funciona bajo cualquiera que los adopte:
// TC39 Signals: el dialecto neutral, propiedad de nadie
const contar = new Signal.State(0);
const doble = new Signal.Computed(() => contar.get() * 2);
contar.set(contar.get() + 1);
console.log(doble.get());
Reconoces el patrón al instante: estado con .get() y .set(), derivado con .get(), la misma trinidad de siempre. Si el estándar prospera, los cinco dialectos podrían converger hacia él como su núcleo compartido, y cada framework quedaría como una capa de ergonomía y de render sobre un motor reactivo común. La lógica de estado se escribiría una vez y viviría bajo cualquier vista.
flowchart TD SO[Solid createSignal] --> TC[TC39 Signal.State y Signal.Computed] AN[Angular signal] --> TC PR[Preact signal] --> TC VU[Vue ref] --> TC SV[Svelte 5 runes] --> TC style TC fill:#a6e3a1,color:#11111b style SO fill:#89b4fa,color:#11111b style SV fill:#cba6f7,color:#11111b
El corolario práctico de todo el nivel: invierte tu tiempo en entender el signal, el computed y el efecto como conceptos, no en memorizar la sintaxis de un framework concreto. Cuando cambies de proyecto, de empleo o de moda, la sintaxis se reaprende en una tarde; el modelo, en cambio, viaja contigo intacto —hacia los cinco dialectos de hoy y hacia el estándar de mañana—. Esa es la inversión con el mejor interés compuesto que puedes hacer en el frontend de 2026.
Que cinco equipos independientes, con filosofías distintas y a veces rivales, hayan llegado por caminos separados al mismo modelo es la señal más fuerte que un patrón puede emitir sobre su propia validez. No fue coordinación: fue convergencia evolutiva, la clase de coincidencia que en la naturaleza produce el ojo en linajes que jamás se cruzaron, porque la solución es tan buena que el problema empuja hacia ella desde cualquier punto de partida. React sostuvo durante años el modelo de re-render del componente entero, y funcionó, pero al precio de un DOM virtual que reconcilia árboles y de una carga cognitiva de dependencias declaradas a mano que hay que mantener sincronizadas. Los signals ofrecen otra respuesta a la misma pregunta —cómo propago un cambio a la interfaz— y lo hacen con grano fino: en lugar de recalcular el componente y comparar árboles, actualizan exactamente el nodo del DOM que lee el valor que cambió, sin intermediario que reconciliar. Esa diferencia, que empezó como una peculiaridad de Solid, terminó absorbida por Angular en su núcleo, adoptada por Vue como su motor de siempre, ofrecida por Preact como capa opcional y llevada al extremo por Svelte, que la hornea en el compilador. Cuando el ecosistema entero converge así, la lección para ti es liberadora: deja de aprender frameworks y aprende el modelo. Un signal es un valor que rastrea a quien lo lee y notifica a quien depende; un computed es una derivación cacheada y perezosa; un efecto es una reacción planificada. Esas tres ideas, más el rastreo automático que las cose, son transferibles sin fricción entre los cinco dialectos y hacia el estándar de TC39 que los unificará a todos. La sintaxis es ropa de temporada; el modelo es el cuerpo. Quien memoriza createSignal sabe un framework; quien entiende el signal sabe todos, incluido el que aún no se ha escrito. Ese es el verdadero premio de este nivel: no cinco herramientas, sino una idea que las contiene.
- Escribe el contador con doble derivado en los cinco dialectos y subraya qué línea hace de estado, cuál de derivado y cuál de lectura en cada uno.
- Clasifica los cinco según su forma de acceso: llamada a función,
.valueo runes de compilador. - Explica por qué Svelte puede prescindir de
.valuey qué precio paga a cambio. - Toma un componente que conozcas en un framework y descríbelo con el vocabulario neutro de signal, computed y efecto.
- Argumenta por qué entender el modelo importa más que memorizar la sintaxis de uno solo.