Svelte 5
How to migrate from Svelte 4 and Tailwind 3 to Svelte 5.
Note: With Svelte 5 comes significant changes to this project, along with the headless UI library used bits-ui. This guide is specifically focused on migrating the shadcn-svelte portions and does not cover the migration of bits-ui
. See Bits UI's migration guide for more information.
Svelte 4 to Svelte 5
This first guide will take your project from Svelte 4 with Tailwind 3 to Svelte 5 and Tailwind 3. Tailwind 3 is still supported by the @next
CLI.
Once you've completed this guide and you're comfortable everything is working, you can move on to the next guide to migrate to Tailwind 4.
Prerequisites
- Ensure you have read up on the changes from Svelte 4 to Svelte 5. Svelte provides a comprehensive guide for this on their website.
- Commit any pending changes to your repository.
- Determine which of your components have custom behavior/styles so that you can reimplement those after updating.
- Use
sv-migrate
to help you migrate your project to Svelte 5.
Update Configs
The components.json
, utils
, and the global CSS file have changed for Svelte 5.
Update components.json
Add the registry
to the root object, and add hooks
, ui
, and lib
keys under aliases
.
{
"$schema": "https://next.shadcn-svelte.com/schema.json",
"style": "default",
"tailwind": {
"css": "src/app.css",
"baseColor": "slate"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils",
+ "ui": "$lib/components/ui",
+ "hooks": "$lib/hooks",
+ "lib": "$lib"
},
"typescript": true,
+ "registry": "https://next.shadcn-svelte.com/registry"
}
Update tailwind.config.js
Add tailwindcss-animate
.
Add the tailwindcss-animate
plugin, sidebar colors, and animations config.
import type { Config } from "tailwindcss";
import tailwindcssAnimate from "tailwindcss-animate";
const config: Config = {
darkMode: ["class"],
content: ["./src/**/*.{html,js,svelte,ts}"],
safelist: ["dark"],
theme: {
container: {
// unchanged ...
},
extend: {
colors: {
// unchanged ...
sidebar: {
DEFAULT: "hsl(var(--sidebar-background))",
foreground: "hsl(var(--sidebar-foreground))",
primary: "hsl(var(--sidebar-primary))",
"primary-foreground": "hsl(var(--sidebar-primary-foreground))",
accent: "hsl(var(--sidebar-accent))",
"accent-foreground": "hsl(var(--sidebar-accent-foreground))",
border: "hsl(var(--sidebar-border))",
ring: "hsl(var(--sidebar-ring))",
},
},
borderRadius: {
// unchanged ...
},
fontFamily: {
// unchanged ...
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--bits-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--bits-accordion-content-height)" },
to: { height: "0" },
},
"caret-blink": {
"0%,70%,100%": { opacity: "1" },
"20%,50%": { opacity: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"caret-blink": "caret-blink 1.25s ease-out infinite",
},
},
},
plugins: [tailwindcssAnimate],
};
export default config;
Update utils.ts
Note: You may not want to do this step until after you've update your components, as some components may rely on the now removed flyAndScale
function.
The only function now exported from utils.ts
is cn
:
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Upgrade Components
Alias Dependencies (optional)
If you plan to slowly migrate components, it's recommended to alias the old versions of the major dependencies, like bits-ui
, in your package.json
file so that you can use both versions of the library in your project while you migrate.
{
"devDependencies": {
- "bits-ui": "^0.22.0",
+ "bits-ui-old": "npm:bits-ui@0.22.0",
}
}
You'll then want to replace all the imports used in your project to bits-ui-old
.
<script lang="ts">
- import { Dialog as DialogPrimitive } from "bits-ui";
+ import { Dialog as DialogPrimitive } from "bits-ui-old";
</script>
You can do the same for any of the other dependencies that you're using in your project.
Update Dependencies
The following dependencies have been updated to support Svelte 5:
bits-ui
-^1.0.0
svelte-sonner
-^1.0.0
@lucide/svelte
-^0.482.0
paneforge
-^1.0.0-next.5
vaul-svelte
-^1.0.0-next.7
mode-watcher
-^1.0.0
cmdk-sv
- deprecated in favor of Bits UI'sCommand
componentsvelte-headless-table
- deprecated in favor of@tanstack/table-core
svelte-radix
- icons deprecated in favor of@lucide/svelte
lucide-svelte
- replaced with@lucide/svelte
You can update your dependencies by running the following command:
Start Migrating Components
Now you're ready to begin updating your components to their new versions. The CLI doesn't actually update your components, it simply replaces them with the new versions, so be sure to commit your changes before running the CLI.
git add .
git commit -m 'before migration'
Now you can run the add
command to start migrating your components.
Review the diff to see what was updated and make any necessary adjustments. Rinse and repeat for each component you want to migrate.
Remove Unused Dependencies
Once you've updated all your components, you can remove the old dependencies from your package.json
file.
cmdk-sv
cmdk-sv
has been replaced with Bits UI's Command
component.
svelte-headless-table
svelte-headless-table
has been replaced with @tanstack/table-core
.
svelte-radix
svelte-radix
has been replaced with @lucide/svelte
.
lucide-svelte
lucide-svelte
has been replaced with @lucide/svelte
.
Next Steps
Once you've completed this guide and you're comfortable everything is working as expected, you can move on to the Tailwind 4 Guide.