Signals en JavaScript: La Propuesta TC39 Que Podria Traer Reactividad Nativa al Lenguaje
Hola HaWkers, una propuesta que esta ganando momentum en TC39 podria cambiar fundamentalmente como construimos interfaces reactivas en JavaScript. Signals, un primitivo de reactividad ya usado por Angular, Vue, Solid y Svelte, esta siendo considerado para inclusion en la especificacion oficial de ECMAScript.
Si trabajas con frontend moderno, esta propuesta merece tu atencion. Vamos a entender que son Signals, como funciona la propuesta y que significa esto para el futuro del desarrollo web.
Que Son Signals
Signals son primitivos de reactividad que permiten crear valores que automaticamente notifican a los dependientes cuando cambian. Piensa en ellos como variables inteligentes que saben quien las esta usando.
El Concepto Basico
La idea fundamental es simple pero poderosa:
// Pseudocodigo ilustrativo del concepto
const count = signal(0); // Crea un signal con valor inicial 0
const doubled = computed(() => count.value * 2); // Derivado automaticamente
console.log(doubled.value); // 0
count.value = 5; // Cambia el signal
console.log(doubled.value); // 10 - automaticamente actualizadoPor Que Importan los Signals
Problemas que Signals resuelven:
Actualizaciones granulares: En lugar de re-renderizar componentes enteros, solo lo que depende del valor cambia
Sincronizacion automatica: Los valores derivados son siempre consistentes con sus fuentes
Performance predecible: El sistema sabe exactamente que necesita actualizar
Simplicidad de modelo mental: Menos conceptos que sistemas como Redux
La Propuesta TC39
La propuesta de Signals para JavaScript esta siendo desarrollada colaborativamente entre representantes de varios frameworks.
Quien Esta Involucrado
Autores de la propuesta:
- Rob Eisenberg (Microsoft/Angular)
- Daniel Ehrenberg (Bloomberg/Igalia)
- Contribuciones de maintainers de Vue, Solid, Svelte
Objetivo declarado:
"Crear una base comun de reactividad que permita interoperabilidad entre frameworks y reduzca duplicacion de codigo."
Lo Que Incluye La Propuesta
La propuesta define dos primitivos principales:
Signal.State:
// Signal basico que guarda un valor
const counter = new Signal.State(0);
// Leyendo el valor
console.log(counter.get()); // 0
// Escribiendo el valor
counter.set(counter.get() + 1);
console.log(counter.get()); // 1Signal.Computed:
const firstName = new Signal.State("John");
const lastName = new Signal.State("Doe");
// Computed que deriva de otros signals
const fullName = new Signal.Computed(() => {
return `${firstName.get()} ${lastName.get()}`;
});
console.log(fullName.get()); // "John Doe"
firstName.set("Jane");
console.log(fullName.get()); // "Jane Doe" - actualizado automaticamenteLo Que NO Esta En La Propuesta
Importante entender los limites:
No incluido:
- Sistema de efectos (side effects)
- Batching automatico
- Integracion con DOM
- Scheduling de actualizaciones
Por que?
"La propuesta es intencionalmente minimal para permitir que frameworks implementen sus propias semanticas sobre la base comun."
Como Frameworks Ya Usan Signals
Para entender la propuesta, es util ver como frameworks existentes implementan reactividad.
Angular Signals
Angular adopto Signals oficialmente en versiones recientes:
import { signal, computed, effect } from '@angular/core';
@Component({
template: `
<button (click)="increment()">
Count: {{ count() }}
</button>
<p>Double: {{ doubleCount() }}</p>
`
})
export class CounterComponent {
count = signal(0);
doubleCount = computed(() => this.count() * 2);
increment() {
this.count.update(value => value + 1);
}
constructor() {
effect(() => {
console.log(`Count changed to: ${this.count()}`);
});
}
}Vue Reactivity
Vue 3 usa un sistema similar llamado refs:
import { ref, computed, watchEffect } from 'vue';
const count = ref(0);
const doubled = computed(() => count.value * 2);
watchEffect(() => {
console.log(`Count is now: ${count.value}`);
});
// En template: {{ count }} y {{ doubled }}SolidJS Signals
SolidJS fue pionero en signals para el frontend:
import { createSignal, createEffect, createMemo } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
createEffect(() => {
console.log(`Count changed to: ${count()}`);
});
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count()} | Doubled: {doubled()}
</button>
);
}
Beneficios de la Estandarizacion
Por que incluir Signals en el lenguaje en lugar de dejarlo como esta?
Interoperabilidad Entre Frameworks
Actualmente, signals de diferentes frameworks son incompatibles:
Problema actual:
- Un signal de Angular no funciona en Vue
- Componentes de diferentes frameworks no comparten estado
- Bibliotecas necesitan elegir cual sistema soportar
Con estandarizacion:
- Base comun permitiria interoperabilidad
- Bibliotecas podrian trabajar con cualquier framework
- Migracion entre frameworks seria mas simple
Reduccion de Bundle Size
Cada framework carga su propia implementacion de reactividad:
Tamano actual de implementaciones:
- Angular Signals: ~8KB
- Vue Reactivity: ~12KB
- SolidJS: ~7KB
- Preact Signals: ~3KB
Con implementacion nativa:
- Cero KB adicional (parte del runtime)
- Optimizaciones de engine posibles
- Performance potencialmente mejor
Modelo Mental Unificado
Los desarrolladores aprenden el concepto una vez:
Actualmente:
- Cada framework tiene nomenclatura diferente
- APIs varian (get/set vs .value vs funcion)
- Comportamientos sutilmente diferentes
Con estandar:
- Un concepto, una API
- Documentacion centralizada
- Transferencia de conocimiento simplificada
Desafios y Controversias
La propuesta no es unanime. Existen debates importantes en la comunidad.
El Debate React
React no usa Signals internamente:
Posicion del equipo React:
- Prefieren modelo de inmutabilidad
- Signals pueden incentivar mutacion
- Complejidad adicional para casos de uso de React
Contraargumento:
- React podria implementar capa sobre Signals
- No es obligatorio usar, solo disponible
- Otros patterns tambien existen (clases, closures)
Complejidad de la Especificacion
Algunos argumentan que Signals son muy opinados para el lenguaje:
Preocupaciones:
- JavaScript nunca tuvo primitivos de UI antes
- Puede incentivar patterns especificos
- Implementacion de engine es compleja
Respuesta de los autores:
- Signals son utiles mas alla de UI (observables, data sync)
- Propuesta es minimal y extensible
- Ya existen primitivos complejos (Proxy, WeakMap)
Performance En Casos Extremos
Sistemas reactivos pueden tener overhead:
Problemas potenciales:
- Tracking de dependencias tiene costo
- Muchos signals = mucha memoria
- Cascadas de actualizaciones
Mitigaciones propuestas:
- Evaluacion lazy por defecto
- Batching de notificaciones
- Referencias debiles para cleanup
Ejemplo Practico: Implementando Un Formulario
Ve como Signals nativos podrian funcionar en un escenario real:
// Con la propuesta, seria algo asi:
const form = {
email: new Signal.State(''),
password: new Signal.State(''),
confirmPassword: new Signal.State('')
};
// Validaciones derivadas
const emailValid = new Signal.Computed(() => {
const email = form.email.get();
return email.includes('@') && email.includes('.');
});
const passwordsMatch = new Signal.Computed(() => {
return form.password.get() === form.confirmPassword.get();
});
const formValid = new Signal.Computed(() => {
return emailValid.get() &&
form.password.get().length >= 8 &&
passwordsMatch.get();
});
// Uso en framework ficticio
function renderForm() {
return html`
<form>
<input
type="email"
value=${form.email.get()}
oninput=${e => form.email.set(e.target.value)}
class=${emailValid.get() ? 'valid' : 'invalid'}
/>
<input
type="password"
value=${form.password.get()}
oninput=${e => form.password.set(e.target.value)}
/>
<input
type="password"
value=${form.confirmPassword.get()}
oninput=${e => form.confirmPassword.set(e.target.value)}
class=${passwordsMatch.get() ? '' : 'error'}
/>
<button disabled=${!formValid.get()}>
Submit
</button>
</form>
`;
}
Timeline y Estado Actual
Donde esta la propuesta en el proceso del TC39.
Etapa Actual
Estado: Stage 1 (Proposal)
Esto significa:
- El comite concuerda que el problema vale resolver
- La propuesta esta siendo activamente desarrollada
- Todavia hay cambios significativos posibles
- No esta lista para implementacion
Proximos Pasos
Para Stage 2:
- Especificacion inicial completa
- Semantica bien definida
- Ejemplo de implementacion
Para Stage 3:
- Implementacion en al menos un engine
- Feedback de uso real
- Especificacion estable
Para Stage 4:
- Multiples implementaciones
- Tests de conformidad
- Aprobacion final
Prediccion Conservadora
Timeline estimada:
- 2026: Refinamiento de la propuesta
- 2027: Posible Stage 2/3
- 2028+: Implementaciones en navegadores
- 2029+: Uso en produccion seguro
Como Prepararse
Aunque la propuesta tarde, puedes prepararte.
Aprende Signals Ahora
Usa una de las implementaciones existentes:
// Preact Signals - muy similar a la propuesta
import { signal, computed, effect } from '@preact/signals';
const count = signal(0);
const doubled = computed(() => count.value * 2);
effect(() => {
console.log(doubled.value);
});Entiende Los Fundamentos
Conceptos que transfieren a cualquier implementacion:
- Tracking de dependencias automatico
- Evaluacion lazy vs eager
- Batching y scheduling
- Cleanup y lifecycle
Reflexion Final
La propuesta de Signals en TC39 representa una posible evolucion fundamental de JavaScript para aplicaciones reactivas. Unificar como frameworks manejan reactividad podria simplificar el ecosistema y mejorar la interoperabilidad.
Los puntos clave:
- Signals son primitivos de reactividad ya probados en frameworks
- La propuesta TC39 busca estandarizacion, no reemplazo de frameworks
- Beneficios incluyen interoperabilidad y reduccion de codigo
- Timeline es larga - probablemente 2028+ para uso en produccion
- Aprender signals ahora te prepara para el futuro
Independiente de cuando (o si) la propuesta sea aprobada, entender reactividad basada en signals ya es valioso hoy. Angular, Vue, Solid y otros frameworks ya adoptaron el pattern, y la tendencia continua creciendo.
Si quieres explorar mas sobre las novedades de JavaScript moderno, te recomiendo que eches un vistazo a otro articulo: ES2026: Las Nuevas Features Que Van a Cambiar Tu Codigo donde descubriras otras propuestas importantes en desarrollo.

