Cómo migrar a SvelteKit 3: qué cambia y en qué orden
SvelteKit 3 lleva la configuración a Vite, cambia $lib por #lib y renueva variables y errores. Qué cambia y cómo migrar a SvelteKit 3, paso a paso.
Basado en fuentes. Escrito a partir de los documentos, reportes y reseñas enlazados en el texto. The Ruling Desk no probó nada de esto en persona. Cómo trabajamos

SvelteKit 3 ya salió, y si tienes una app en SvelteKit 2, migrar a SvelteKit 3 toca tu archivo de configuración, tus imports, tus variables de entorno y tu manejo de errores. El equipo de Svelte lo publicó el 1 de octubre de 2026, con un comando de migración que convierte todo el código que puede y deja una lista de pendientes para el resto. Esta guía repasa lo que de verdad cambia y en qué orden atacarlo, a partir de la guía de migración oficial. Describimos los pasos documentados; no los ejecutamos en una app en producción.
Puntos clave
- SvelteKit 3.0.0 se publicó el 1 de octubre de 2026. La configuración pasa de
svelte.config.jsavite.config.ts, y el alias$libse convierte en#lib. - El comando
npx sv migrate sveltekit-3automatiza nueve tareas documentadas, pero cambiar$libpor#libes un paso manual, según el equipo de Svelte. - Las variables de entorno ahora viven en un solo archivo,
src/env.ts, y todos los errores, incluidos los que lanzas conerror(), pasan ahora porhandleError. - Necesitas Node 22.17, TypeScript 6 y Vite 8.0.12 o más nuevos antes de empezar.
- Las remote functions siguen siendo experimentales en la 3.0 y necesitan la opción de Async Svelte.
Qué cambia en SvelteKit 3
El anuncio del lanzamiento enumera los cambios principales: la configuración ahora vive en vite.config.ts en lugar de svelte.config.js, $lib pasa a ser #lib usando subpath imports estándar, las variables de entorno estrenan un sistema explícito, los service workers necesitan menos código repetitivo y el manejo de errores se renueva por completo. Las notas de la versión 3.0.0 en GitHub tienen fecha del 1 de octubre de 2026, a las 17:21 UTC.
Las razones tienen que ver, sobre todo, con eliminar código de enlace entre herramientas. En la publicación de la release candidate del 13 de agosto, el equipo explicó que poner la configuración en el archivo de Vite le da al plugin de Vite tus ajustes de inmediato, sin una búsqueda asíncrona. El cambio a #lib se apoya en los subpath imports de Node, que Vite y TypeScript ya entienden, así que SvelteKit ya no tiene que mantener su propio alias sincronizado entre herramientas.
Varias APIs antiguas desaparecen o quedan obsoletas. La guía de migración dice que $app/stores se elimina en favor de $app/state, que base, assets y resolveRoute salen de $app/paths, que el módulo $service-worker se borra y que $app/environment se renombra a $app/env.
Lo que sigue siendo experimental
Las remote functions, la forma de SvelteKit de llamar código del servidor desde el cliente con tipos seguros, no están terminadas. El anuncio dice que son la prioridad número uno del equipo y que todavía requieren la función experimental Async Svelte. La guía de migración indica que se activan con experimental.remoteFunctions: true más compilerOptions.experimental.async: true. Si tu app no las usa, hoy no cambia nada para ti.
Paso 1: Revisa las nuevas versiones mínimas
Antes de ejecutar nada, la guía de migración enumera estos mínimos:
| Dependencia | Mínimo para SvelteKit 3 |
|---|---|
| Node | 22.17 |
| TypeScript | 6 |
| Svelte | 5.57.1 (el changelog de la 3.0.0 dice 5.56.4) |
| Vite | 8.0.12 |
@sveltejs/vite-plugin-svelte | 7 |
Actualiza primero Node y TypeScript en tu CI y tu hosting, porque viven fuera de tu repositorio. Después haz commit o stash de tu trabajo: la documentación de sv migrate dice que la herramienta pregunta antes de modificar archivos cuando tu árbol de trabajo de git tiene cambios, y un árbol limpio hace que su diff sea fácil de revisar.
Paso 2: Ejecuta sv migrate para migrar a SvelteKit 3
El anuncio da el comando de una sola pasada, npx sv migrate sveltekit-3 --tasks all --confirm, que aplica todas las tareas sin preguntar y escribe una lista de pendientes con lo que no puede resolver. Ejecuta npx sv migrate sveltekit-3 sin opciones si prefieres elegir las tareas una por una. Según la documentación de sv, las nueve tareas son:
- package-json: actualiza las versiones de los paquetes.
- tsconfig: extiende el
$app/tsconfiggenerado en lugar de.svelte-kit/tsconfig.json. - svelte-config: mueve los ajustes compatibles de
svelte.config.*avite.config.*. - environment: reemplaza los módulos de entorno antiguos por
$app/env. - paths: migra las APIs eliminadas de
$app/pathsy sus tipos de ruta. - external-redirects: activa el nuevo comportamiento en las redirecciones externas.
- shallow-routing: reemplaza
pushStateyreplaceStatepor llamadas agoto. - params: reúne los matchers de parámetros de ruta en
src/params.ts(o.js). - app-state: pasa el uso de
$app/storesa$app/state.
Otras opciones de la documentación son --files, para limitar la ejecución a un patrón glob, --no-install, para no instalar dependencias al final, y --no-git-check, para saltarte la pregunta sobre cambios sin guardar en git.
Paso 3: Cambia $lib por #lib a mano
Ninguna de las nueve tareas cubre el alias, y la publicación de la release candidate dice que las rutas de import se actualizan manualmente. La guía de migración muestra la configuración: agrega un campo imports a package.json y luego reemplaza $lib por #lib en todo tu código.
{
"imports": {
"#lib": "./src/lib/index.js",
"#lib/*": "./src/lib/*"
}
}
El detalle está en las extensiones de archivo. Los subpath imports no adivinan, así que $lib/utils se convierte en #lib/utils.ts, y un import de carpeta pasa a ser #lib/foo/index.ts. Un buscar y reemplazar en todo el proyecto te lleva casi todo el camino; tu verificador de tipos marcará los imports que sigan sin extensión.
Paso 4: Lleva las variables de entorno a src/env.ts
Los módulos $env/* siguen funcionando, pero están obsoletos, y la documentación de variables de entorno dice que se eliminarán en SvelteKit 4. El nuevo sistema te pide declarar cada variable en src/env.ts con defineEnvVars, que ahora se importa desde @sveltejs/kit/env. Cada entrada puede definir:
public: se puede enviar al navegador (las variables son privadas por defecto);static: se incrusta al compilar, así que el valor queda fijo en lo que existía durante el build;schema: una función de validación o una librería de Standard Schema como Zod o Valibot;description: una nota que aparece en tu editor.
Después importas los valores privados desde $app/env/private y los públicos desde $app/env/public. La documentación dice que la app no arranca ni compila si la validación falla, así que una variable faltante o inválida se detecta al iniciar o compilar, no más tarde en producción.
Paso 5: Revisa tu manejo de errores
Este es el paso con más probabilidades de cambiar el comportamiento sin romper el build. Según la guía de migración:
handleErrorahora recibe todos los errores, incluidos los que lanzas a propósito conerror().error()recibe un mensaje de texto como segundo argumento; cualquier propiedad extra pasa a un tercer argumento.handleValidationErrorse elimina. Los errores de validación llegan ahandleErrorconkind: 'validation'.App.Errorsiempre incluye unstatus, yhandleErrorpuede devolver unstatuspara fijar el código HTTP.- Los errores de renderizado ahora también pasan por
handleErrory por los límites de+error.svelte, no solo los errores de carga. - Las form actions mejoradas responden con el código de estado que pasaste a
fail().
Si tu handleError envía registros a un rastreador de errores, espera más eventos, porque los 404 intencionales ahora pasan por ahí. Filtra por status si no los quieres.
Paso 6: Corrige navegación, cookies y adaptadores
La guía de migración señala varios cambios incompatibles más pequeños que vale la pena buscar en tu código:
goto()ahora rechaza cuando una URL no corresponde a una ruta de tu app. Usawindow.location.hrefpara enlaces externos.invalidateAllqueda obsoleto en favor derefreshAll(), que conservapage.state.redirect()hacia otro sitio necesita{ external: true }(la tarea de migración external-redirects está pensada para agregarlo).- Las cookies sin un
pathexplícito ahora usan'/'por defecto, así que aplican en todo el sitio. csrf.checkOrigindesaparece; la protección CSRF siempre está activa, concsrf.trustedOriginscomo lista de orígenes permitidos.json()ytext()quedan obsoletos; usaResponse.json()ynew Response(text).
Los adaptadores también cambian. La guía dice que adapter-node elimina la variable de entorno ORIGIN en favor de paths.origin, que adapter-vercel ya no admite el edge runtime, que adapter-cloudflare necesita wrangler ^4.67.0 e importa las APIs de Cloudflare desde cloudflare:workers, y que adapter-netlify necesita Netlify CLI 17.31.0 o más nuevo.
Paso 7: Resuelve la lista de pendientes y prueba
Termina con la lista que generó la herramienta de migración y luego ejecuta tu verificador de tipos, tus pruebas y un build de producción. Recorre formularios, redirecciones y cualquier página que escriba cookies, porque esos son los cambios de comportamiento que un compilador no detecta. Para más sobre frameworks y herramientas, consulta nuestra sección de software y todo lo etiquetado como SvelteKit.
Solución de problemas
- Los imports no se resuelven después del cambio. Revisa si falta la extensión
.tso.jsen los imports de#liby confirma que el campoimportsestá en elpackage.jsonraíz. - Una redirección a otro sitio lanza un error. Agrega
{ external: true }, o una lista de orígenes permitidos, a la llamada aredirect(). - Se rechaza un envío de formulario desde otro origen. La guía dice que la falta del encabezado
Content-Typeahora se trata como CSRF; agrega el encabezado o incluye el origen encsrf.trustedOrigins. - Una respuesta 204 perdió su cuerpo. Es intencional: las respuestas 2xx vacías ahora no devuelven contenido, según la especificación HTTP.
- Tu service worker ya no encuentra
$service-worker. Importaversiondesde$app/env, las listas de archivos desde$app/manifesty las rutas desde$app/paths.
En resumen
Creemos que, para la mayoría de las apps en SvelteKit 2, migrar a SvelteKit 3 es una revisión cuidadosa y no una reescritura: actualiza tus herramientas, ejecuta sv migrate, haz el cambio a #lib a mano y dedica tiempo de verdad al manejo de errores, que es donde el comportamiento cambia sin avisar. Si dependes de las remote functions, sigue tratándolas como experimentales. Un hilo de Hacker News sobre el lanzamiento superaba los 170 comentarios al 3 de octubre de 2026, y algunos participantes dicen que ya usan remote functions en producción; es su decisión, no una garantía del equipo de Svelte. Lo siguiente que hay que vigilar en el blog de Svelte es el avance de las remote functions.
Preguntas frecuentes
¿SvelteKit 3 es estable?
Sí. La versión 3.0.0 se publicó como versión estable el 1 de octubre de 2026, después de una release candidate anunciada el 13 de agosto. Las remote functions que incluye siguen siendo experimentales.
¿sv migrate cambia $lib por #lib?
No. Las tareas documentadas de sveltekit-3 no lo incluyen, y el equipo de Svelte dice que las rutas de import se actualizan a mano. Agregas un campo imports a package.json y reemplazas los imports, con extensiones de archivo.
¿Qué versión de Node necesita SvelteKit 3?
La guía de migración indica Node 22.17 como mínimo, junto con TypeScript 6 y Vite 8.0.12.
¿Tengo que mover mis variables de entorno de inmediato?
No de inmediato. Los módulos $env/* están obsoletos en SvelteKit 3, no eliminados, y la documentación dice que se eliminarán en SvelteKit 4. Pasar a src/env.ts desde ahora te da validación y seguridad de tipos.