I saw the JulyâŊ2026 Svelte blog post and it immediately clicked for me: the longâstanding svelte.config.js file can now live inside the Vite configuration. As someone who maintains several SvelteKit apps, that change feels like a real productivity boost, especially when youâre already juggling Vite plugins, environment variables, and custom build steps. In this post Iâll walk through why the shift matters, show the exact code you need to adopt, and discuss the practical tradeâoffs before you decide to upgrade.
Why this change matters right now
SvelteKit has always been built on top of Vite, but the two configs lived in separate files:
ââ vite.config.js
ââ svelte.config.js â Svelteâspecific settings
ââ src/
That split caused a few friction points:
-
Duplicate context â Both files expose a
defineConfigwrapper, so you end up repeatingimport { sveltekit } from '@sveltejs/kit/vite'and then merging options manually. -
Orderâsensitive plugins â Some Vite plugins need to run before SvelteKitâs own plugin, but the only reliable way to guarantee order was to edit
vite.config.jsand then remember to keepsvelte.config.jsin sync. - Tooling confusion â IDEs and typeâcheckers sometimes struggle to infer the final shape of the combined config, leading to falseâpositive warnings.
The JulyâŊ2026 release (SvelteKitâŊ2.0) removes the need for a separate svelte.config.js. By exporting a kit key inside vite.config.js, the framework can read its own configuration directly from Viteâs config object. This means a single source of truth for everything that touches the build pipeline.
The old way â a quick refresher
If youâre still on a preâJulyâŊ2026 version, your project likely looks like this:
// svelte.config.js
import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
export default {
kit: {
adapter: adapter(),
// other SvelteKitâspecific options
},
preprocess: preprocess()
};
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()],
// Viteâonly options here
});
Every time you add a Vite plugin that must run before SvelteKit, you have to tinker with the plugins array order, and you still need to keep the two config files in sync for things like alias resolution.
The new approach â everything in vite.config.js
Starting with SvelteKitâŊ2.0 (JulyâŊ2026), you can drop svelte.config.js entirely and embed the kit configuration under the sveltekit key inside Viteâs config. Hereâs a minimal example:
// vite.config.js
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import eslintPlugin from 'vite-plugin-eslint';
export default defineConfig({
plugins: [
// SvelteKit must stay first unless you have a reason to reorder
sveltekit({
// <-- SvelteKitâspecific options go here
kit: {
adapter: adapter(),
// any other kit options (paths, prerender, etc.)
},
preprocess: preprocess()
}),
// Viteâonly plugins follow
eslintPlugin()
],
// Viteâlevel config (aliases, server, etc.) stays as usual
resolve: {
alias: {
$components: '/src/lib/components'
}
}
});
A few things to note:
- The
sveltekitfunction now accepts an object that mirrors the oldsvelte.config.jsshape (kit,preprocess, etc.). - You still import the same adapters and preprocessors; nothing changes under the hood.
- All Vite plugins live in the same
pluginsarray, so ordering is explicit and obvious.
If you already have a svelte.config.js, simply copy its exported object into the sveltekit({ âĶ }) call and delete the file. Vite will pick up the merged configuration automatically.
Stepâbyâstep migration checklist
- Upgrade to SvelteKitâŊ2.0
npm i -D @sveltejs/kit@2.0 vite@5.0
(Both packages are released together, so the peer dependency alignment is safe.)
Remove
svelte.config.jsâ Back it up first, just in case.Add the
kitblock tovite.config.jsâ Use the snippet above as a template.
If you have custom Vite plugins that previously referencedsvelte.config.js, adjust the import paths accordingly.Run the dev server â
npm run dev. The CLI will now report that it is reading configuration fromvite.config.js.Verify build output â
npm run build. The generatedbuild/folder should be identical to the preâupgrade version, assuming you havenât changed any other options.Update CI scripts â If your CI pipeline explicitly copies
svelte.config.jsinto a Docker image or caches it, remove that step.
What else is new in JulyâŊ2026?
While the config merge is the headline, the same release also introduced a few related improvements that make the change feel natural:
-
Typed Vite config for SvelteKit â The
sveltekithelper now returns a fully typedUserConfigobject, so TypeScript users get autocomplete for both Vite and SvelteKit options in the same file. -
Improved error messages â If you accidentally place
kitoptions outside thesveltekit({ âĶ })call, the dev server throws a clear âSvelteKit config must be passed to the sveltekit pluginâ error. - Better SSR handling â The new config path aligns with Viteâs SSR entry points, making it easier to add custom server middleware without a second config file.
These tweaks are incremental, but they reinforce the idea that SvelteKit is now a firstâclass Vite plugin rather than a sibling framework.
My personal take: upgrade or not?
From a dayâtoâday perspective, consolidating the two config files reduces mental overhead. I no longer have to open two files to add a new alias or to tweak a Vite plugin order; everything lives where Vite already expects it. The migration is straightforwardâjust copyâpaste the old kit object into the sveltekit callâand there are no breaking runtime changes.
The only tradeâoff is that you now have a single point of failure: a typo in vite.config.js can break both Vite and SvelteKit simultaneously. That risk is mitigated by
Top comments (8)
Great article, Frank!
Thanks! Hope it helps simplify your SvelteKit config.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.