Lo que se viene con Svelte 5

Svelte 5 es la próxima versión del popular framework de aplicaciones web. Entre las novedades de esa versión: runas, una nueva forma de organizar las aplicaciones mediante funciones más fáciles de entender para mantener estado, derivar estado, ejecutar efectos... o una nueva forma de declarar eventos mucho más simple.

Este curso ha sido marcado como anticuado y no está siendo revisado de forma activa. Es posible que la información pueda estar desactualizada o que los enlaces se hayan roto.

Svelte 5 está a punto de llegar y con él vienen cambios que van a transformar la forma en que manejamos eventos, estado y propiedades en nuestros componentes. Aunque todavía no sabemos la fecha exacta de lanzamiento, ya podemos ir preparándonos para adaptar nuestro código a esta nueva versión que promete simplificar y modernizar la experiencia de desarrollo.

Uno de los cambios más visibles será la forma en que declaramos los manejadores de eventos. Hasta ahora, en Svelte usábamos la sintaxis on:evento, como on:click o on:blur. En Svelte 5, esta sintaxis se simplifica eliminando los dos puntos, por lo que ahora escribiremos directamente onClick, onMouseMove, onEnter, etc. Esto hace que los eventos se traten como props normales que se pasan a los componentes, lo que abre la puerta a una escritura más cómoda y coherente. Por ejemplo, si tenemos una función llamada onClick, podemos pasarla directamente como prop sin necesidad de asignarla explícitamente con un igual, simplemente usando {onClick}.

Este cambio también implica que la función createEventDispatcher, que usábamos para emitir eventos personalizados desde componentes hijos hacia padres, queda deprecada. En su lugar, se adopta un patrón más parecido al de React: pasamos funciones como props para manejar eventos. Por ejemplo, un componente Pump podría recibir dos props, inflate y deflate, que son funciones que el componente invoca cuando ocurren ciertos eventos internos. Así, el componente padre controla qué hacer cuando se disparan esos eventos, sin necesidad de crear dispatchers personalizados.

Esta nueva forma de manejar eventos también significa que los modificadores como once o preventDefault desaparecen. Si queremos que un evento se ejecute solo una vez, tendremos que implementar esa lógica manualmente dentro del manejador, por ejemplo, devolviendo una función que se desasigne a sí misma tras la primera ejecución. Para evitar que el evento realice su acción por defecto, ahora tendremos que llamar explícitamente a e.preventDefault() dentro del manejador. Aunque esto dispersa un poco la lógica, la ventaja es que toda la información del evento queda centralizada en el manejador mismo.

Otro cambio interesante son los Snippets, una nueva forma de organizar componentes complejos sin necesidad de crear múltiples archivos. Si alguna vez hemos tenido un componente muy grande con varios bucles o secciones repetitivas, probablemente hemos creado componentes hijos para mantener el código limpio, pero esto puede generar muchos archivos y complicar la estructura. Con los Snippets, podemos definir componentes anónimos dentro del mismo archivo usando la etiqueta Snippet y asignándoles un nombre, por ejemplo, Figure. Luego, para renderizarlos, usamos la directiva Render pasando los datos necesarios. Lo mejor es que todos los Snippets dentro de un archivo comparten el mismo contexto, por lo que pueden acceder a las variables definidas en el bloque script sin necesidad de pasar props explícitas. Esto facilita mucho la organización y evita la proliferación de archivos.

El cambio más destacado y profundo de Svelte 5 es la introducción del sistema de runas, que son nuevas funciones que comienzan con $ y que permiten manejar estado, efectos y props de forma más clara y explícita. Aunque el sistema tradicional seguirá funcionando por un tiempo, las runas ofrecen una forma más moderna y parecida a la experiencia de React, pero con su propia semántica.

La runa $State reemplaza la forma tradicional de declarar variables con let para el estado interno. En lugar de eso, declaramos el estado con $State pasando el valor inicial, y obtenemos un proxy que intercepta accesos y modificaciones para actualizar el componente de forma reactiva. Por ejemplo, para crear un contador, haríamos algo así:

const count = $State(0);

function increment() {
  count.value++;
}

Luego, en el template, podemos usar {count.value} para mostrar el valor y conectar el evento onClick al método increment.

La runa $Derived sirve para crear estados computados que dependen de otros estados. En lugar de actualizar manualmente valores derivados, declaramos una función que calcula el valor a partir de las dependencias, y Svelte se encarga de actualizarlo automáticamente cuando cambian esas dependencias. Por ejemplo:

const count = $State(0);
const double = $Derived(() => count.value * 2);

Cada vez que count.value cambie, double se actualizará automáticamente y el DOM se repintará con el nuevo valor.

Para quienes vienen de React, la runa $Effect será muy familiar. Permite ejecutar código cuando cambian ciertas variables de estado, sin necesidad de especificar explícitamente las dependencias, ya que el compilador detecta automáticamente qué estados se usan dentro del efecto. Además, podemos devolver una función de limpieza para cancelar intervalos, timeouts u otras suscripciones, igual que en React:

$Effect(() => {
  console.log(`Count ha cambiado a ${count.value}`);

  return () => {
    // Código de limpieza si es necesario
  };
});

Finalmente, la runa $Props introduce una forma más estructurada y clara de declarar las propiedades que recibe un componente. En lugar de usar export let, ahora podemos hacer destructuring con $Props para definir qué props son obligatorias y cuáles tienen valores por defecto. Por ejemplo:

const { requiredProp, optionalProp = 42 } = $Props;

Esto mejora la legibilidad y organización del código, dejando claro qué props espera el componente y cuáles son opcionales.

Estos son los cambios más relevantes que trae Svelte 5, que sin duda van a modificar la manera en que escribimos nuestros componentes, haciéndolos más explícitos, organizados y alineados con patrones modernos de desarrollo. Aunque habrá que acostumbrarse a dejar atrás algunas prácticas tradicionales, la evolución apunta a un código más limpio y mantenible.

Lista de reproducción
  1. 1
    ¿Qué es Svelte?
    9 minutos
  2. 2
    ¿Cómo crear un proyecto de Svelte?
    7 minutos
  3. 3
    Creando nuestro primer componente
    7 minutos
  4. 4
    Datos dinámicos y props
    7 minutos
  5. 5
    Anidando componentes
    7 minutos
  6. 6
    Capturando eventos
    7 minutos
  7. 7
    Eventos y reactividad
    8 minutos
  8. 8
    Atributos condicionales e IF
    9 minutos
  9. 9
    Bucles
    11 minutos
  10. 10
    Bloques await
    7 minutos
  11. 11
    Bind
    8 minutos
  12. 12
    bind:this
    6 minutos
  13. 13
    ¿Para qué nos sirve un evento personalizado?
    6 minutos
  14. 14
    createEventDispatcher
    6 minutos
  15. 15
    Eventos con detalles
    7 minutos
  16. 16
    Reenviando eventos
    6 minutos
  17. 17
    Ejemplo de eventos (primera parte)
    12 minutos
  18. 18
    Ejemplo de eventos (y segunda parte)
    16 minutos
  19. 19
    Modificadores de eventos
    6 minutos
  20. 20
    Fundamentos del CSS con Svelte
    9 minutos
  21. 21
    Clases condicionales
    7 minutos
  22. 22
    Estilos en línea y variables CSS
    8 minutos
  23. 23
    Estilos globales
    6 minutos
  24. 24
    Importar hojas de estilo externas
    5 minutos
  25. 25
    Reactividad experta con el operador $
    8 minutos
  26. 26
    Slots (parte 1 de 2)
    5 minutos
  27. 27
    Slots (parte 2 de 2)
    7 minutos
  28. 28
    Directivas svelte:window, svelte:head, svelte:body
    4 minutos
  29. 29
    Actualizar de Rollbar a Vite 3
    11 minutos
  30. 30
    Exportar a Web Components
    10 minutos
  31. 31
    Integrar TypeScript, SCSS, PostCSS...
    8 minutos
  32. 32
    Hasta aquí (por ahora)
    3 minutos
  33. 33
    Lo que se viene con Svelte 5
    13 minutos