SvelteKit 3: cómo migrar con sv migrate y el cambio de \$lib que el comando no hace por ti
SvelteKit 3.0 salió el 1 de octubre de 2026 y casi toda la migración se automatiza con un comando, npx sv migrate sveltekit-3. Lo que ese comando no hace es cambiar $lib por #lib: ese paso es manual. En esta guía verás qué cambia, qué resuelve la herramienta de migración y qué te toca hacer a ti.
El equipo de Svelte lo presenta como el mismo framework con más pulido y más seguridad de tipos. Para la API del día a día es cierto, pero la estructura del proyecto cambia: la configuración se muda de archivo, el alias de importación más usado se reemplaza, los módulos de variables de entorno quedan obsoletos y los service workers se configuran de otra manera.
¿Qué es SvelteKit y en qué se diferencia de Svelte?
SvelteKit es el framework oficial de aplicaciones para Svelte: se encarga del enrutamiento, la carga de datos, el renderizado en servidor y el despliegue mediante adapters. Es a Svelte lo que Next.js es a React. Svelte compila los componentes y SvelteKit los convierte en una aplicación desplegable, ya sea con renderizado en servidor, prerenderizada como sitio estático o como single-page app. Tiene licencia MIT y se desarrolla en github.com/sveltejs/kit.
¿Qué cambia en SvelteKit 3?
El anuncio oficial destaca cinco cambios, y cuatro de ellos afectan a archivos que ya tienes en tu proyecto.
La configuración pasa de svelte.config.js a vite.config
svelte.config.js ya no está soportado. La configuración ahora se pasa directamente al plugin sveltekit de Vite, y las opciones que antes vivían en config.kit.* pasan a ser opciones de primer nivel del plugin:
import adapter from '@sveltejs/adapter-auto';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
sveltekit({
adapter: adapter()
})
]
});
Las opciones que no son de SvelteKit se reenvían a vite-plugin-svelte. Con la mudanza desaparecen varias opciones:
files.libvitePluginpreloadStrategy-
prerender.origin, reemplazada por la nuevapaths.origin -
csrf.checkOrigin, reemplazada porcsrf.trustedOrigins
$lib pasa a ser #lib
SvelteKit ya no genera el alias $lib. En su lugar declaras tú mismo #lib usando los subpath imports de Node.js, que Vite y TypeScript resuelven de forma nativa. Es el cambio que sv migrate no hace por ti; los pasos están más abajo.
Las variables de entorno pasan a $app/env
Los módulos $env/... quedan obsoletos en favor de $app/env/private y $app/env/public. $app/environment se renombra a $app/env, y ahora también puedes importarlo dentro de un service worker.
Los service workers necesitan menos código repetitivo
El módulo $service-worker se eliminó y sus exportaciones se reparten entre módulos estándar:
-
versionviene de$app/env. -
assets,immutableyprerenderedvienen del nuevo$app/manifest. - Las utilidades de rutas vienen de
$app/paths.
Un nuevo módulo, $app/service-worker, te da un contexto de service worker con tipos. Además, SvelteKit ahora registra el service worker como módulo ES y no como script clásico.
El quinto cambio destacado es el manejo de errores. En SvelteKit 3, handleError recibe todos los errores, incluidos los esperados que creas con error(...), y los errores de renderizado se envían al +error.svelte más cercano.
¿Qué necesitas antes de migrar a SvelteKit 3?
Según la guía oficial de migración, SvelteKit 3 exige estas versiones mínimas:
| Dependencia | Mínimo |
|---|---|
| Node | 22.17 |
| TypeScript | 6 |
| Svelte | 5.57.1 |
| Vite | 8.0.12 |
@sveltejs/vite-plugin-svelte |
7 |
El equipo de Svelte recomienda actualizar primero a la última versión 2.x, porque esa versión muestra avisos de obsolescencia dirigidos exactamente al código que tendrás que cambiar. Haz commit de tu proyecto antes de empezar: si el árbol de trabajo tiene cambios sin confirmar, sv migrate te lo avisará.
¿Cómo migrar a SvelteKit 3 con sv migrate?
El anuncio de lanzamiento propone un comando que lo hace todo de una vez:
npx sv migrate sveltekit-3 --tasks all --confirm
La documentación del CLI recomienda un enfoque más prudente: ejecuta una tarea por vez y haz commit después de cada una, para que cada diff sea fácil de revisar. Para ver las tareas disponibles sin ejecutar nada, usa:
npx sv migrate sveltekit-3 --tasks
La migración sveltekit-3 se compone de nueve tareas. Las dos primeras son requisitos previos y se ejecutan siempre:
| Tarea | Qué hace |
|---|---|
package-json |
Actualiza las versiones de los paquetes para SvelteKit 3 |
tsconfig |
Hace que tu tsconfig.json extienda $app/tsconfig en lugar de .svelte-kit/tsconfig.json
|
svelte-config |
Mueve las opciones soportadas de svelte.config.* a vite.config.*
|
environment |
Reemplaza los módulos de entorno antiguos por $app/env y crea las declaraciones src/env.js o src/env.ts cuando hacen falta |
paths |
Migra las APIs obsoletas de $app/paths (base, assets y resolveRoute se reemplazan por asset() y resolve()) |
external-redirects |
Adapta las redirecciones externas al nuevo comportamiento |
shallow-routing |
Reemplaza pushState y replaceState por goto(..., { shallow: true })
|
params |
Reúne los param matchers en un único src/params.js o src/params.ts
|
app-state |
Migra $app/stores a $app/state
|
Para ejecutar una sola tarea:
npx sv migrate sveltekit-3 --tasks svelte-config
La documentación advierte que el proyecto no tiene por qué funcionar si solo se ejecutaron algunas tareas: la mayoría de las aplicaciones necesitan todas las que les correspondan. La herramienta solo reescribe los patrones que puede identificar con seguridad. Donde no puede, deja un comentario @migration-task, así que busca ese marcador exacto en el proyecto antes de dar la migración por terminada.
¿Cómo arreglar $lib después de migrar a SvelteKit 3?
$lib no aparece en la lista de tareas. Cuando sv migrate termina, cada importación con $lib en tu código sigue apuntando a un alias que SvelteKit 3 ya no genera. Para arreglarlo hacen falta tres pasos.
1. Declara #lib en package.json:
{
"imports": {
"#lib": "./src/lib/index.js",
"#lib/*": "./src/lib/*"
}
}
2. Reemplaza $lib por #lib en todo el código.
3. Añade la extensión de archivo a esas importaciones. Los subpath imports la exigen, así que el cambio no es un simple buscar y reemplazar del prefijo:
// antes
import { foo } from '$lib/foo';
// después
import { foo } from '#lib/foo.js';
La opción files.lib también desapareció: si habías personalizado tu directorio lib, apunta las entradas de imports a ese directorio.
¿Qué más puede romperse en producción?
Estos cambios de la guía de migración modifican el comportamiento en tiempo de ejecución, y algunos no producen ningún error de build:
-
$app/storesse eliminó, no solo quedó obsoleto. La tareaapp-statemigra los archivos.svelte, así que revisa si quedan usos en otros archivos. -
adapter-nodeelimina la variable de entornoORIGIN. Definepaths.originen tu configuración de Vite. -
adapter-vercelya no soporta el runtimeedge. -
Las APIs de Cloudflare salen de
platform. Importaenvdesdecloudflare:workers;cfahora es una propiedad derequest. -
Las redirecciones externas necesitan permiso explícito. Pasa
{ external: true }o una lista de orígenes permitidos aredirect(...). -
Los nombres de cookies deben ser ASCII. SvelteKit ahora usa
cookiev2, que rechaza caracteres no ASCII comoáen los nombres de las cookies. Conviene revisarlo en aplicaciones en español. -
Las cookies usan
path: '/'por defecto, en lugar de la ruta de la petición actual. -
error(...)recibe un string como segundo argumento. Las propiedades adicionales ahora van en un tercer argumento. -
goto()rechaza las URLs que no corresponden a una ruta de tu aplicación. Para navegar a un sitio externo, usawindow.location.href. -
Las respuestas
2xxvacías se devuelven sin cuerpo, como exige la especificación HTTP.
¿Están listas las remote functions en SvelteKit 3?
Todavía no. Al momento de publicar esta nota, las remote functions seguían siendo experimentales: requieren el flag experimental.remoteFunctions junto con la opción asíncrona del compilador de Svelte. El equipo de Svelte las señala como su máxima prioridad. Si las estabas esperando, igual vale la pena actualizar ya, porque la migración no depende de ellas.
Si estás siguiendo otras actualizaciones mayores de esta temporada, ya contamos qué cambia en htmx 4.0 si vienes de htmx 2.
Top comments (0)