--- title: Breaking changes --- While Svelte 5 is a complete rewrite, we have done our best to ensure that most codebases can upgrade with a minimum of hassle. That said, there are a few small breaking changes which may require action on your part. They are listed here. ## Components are no longer classes In Svelte 3 and 4, components are classes. In Svelte 5 they are functions and should be instantiated differently. If you need to manually instantiate components, you should use `mount` or `hydrate` (imported from `svelte`) instead. If you see this error using SvelteKit, try updating to the latest version of SvelteKit first, which adds support for Svelte 5. If you're using Svelte without SvelteKit, you'll likely have a `main.js` file (or similar) which you need to adjust: ```diff + import { mount } from 'svelte'; import App from './App.svelte' - const app = new App({ target: document.getElementById("app") }); + const app = mount(App, { target: document.getElementById("app") }); export default app; ``` `mount` and `hydrate` have the exact same API. The difference is that `hydrate` will pick up the Svelte's server-rendered HTML inside its target and hydrate it. Both return an object with the exports of the component and potentially property accessors (if compiled with `accessors: true`). They do not come with the `$on`, `$set` and `$destroy` methods you may know from the class component API. These are its replacements: For `$on`, instead of listening to events, pass them via the `events` property on the options argument. ```diff + import { mount } from 'svelte'; import App from './App.svelte' - const app = new App({ target: document.getElementById("app") }); - app.$on('event', callback); + const app = mount(App, { target: document.getElementById("app"), events: { event: callback } }); ``` > Note that using `events` is discouraged — instead, [use callbacks](https://svelte-5-preview.vercel.app/docs/event-handlers) For `$set`, use `$state` instead to create a reactive property object and manipulate it. If you're doing this inside a `.js` or `.ts` file, adjust the ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`. ```diff + import { mount } from 'svelte'; import App from './App.svelte' - const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } }); - app.$set('event', { foo: 'baz' }); + const props = $state({ foo: 'bar' }); + const app = mount(App, { target: document.getElementById("app"), props }); + props.foo = 'baz'; ``` For `$destroy`, use `unmount` instead. ```diff + import { mount, unmount } from 'svelte'; import App from './App.svelte' - const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } }); - app.$destroy(); + const app = mount(App, { target: document.getElementById("app") }); + unmount(app); ``` As a stop-gap-solution, you can also use `createClassComponent` or `asClassComponent` (imported from `svelte/legacy`) instead to keep the same API known from Svelte 4 after instantiating. ```diff + import { createClassComponent } from 'svelte/legacy'; import App from './App.svelte' - const app = new App({ target: document.getElementById("app") }); + const app = createClassComponent({ component: App, target: document.getElementById("app") }); export default app; ``` If this component is not under your control, you can use the `compatibility.componentApi` compiler option for auto-applied backwards compatibility, which means code using `new Component(...)` keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add `$set` and `$on` methods for all component instances you get through `bind:this`. ```js /// svelte.config.js export default { compilerOptions: { compatibility: { componentApi: 4 } } }; ``` Note that `mount` and `hydrate` are _not_ synchronous, so things like `onMount` won't have been called by the time the function returns and the pending block of promises will not have been rendered yet (because `#await` waits a microtask to wait for a potentially immediately-resolved promise). If you need that guarantee, call `flushSync` (import from `'svelte'`) after calling `mount/hydrate`. ### Server API changes Similarly, components no longer have a `render` method when compiled for server side rendering. Instead, pass the function to `render` from `svelte/server`: ```diff + import { render } from 'svelte/server'; import App from './App.svelte'; - const { html, head } = App.render({ message: 'hello' }); + const { html, head } = render(App, { props: { message: 'hello' } }); ``` In Svelte 4, rendering a component to a string also returned the CSS of all components. In Svelte 5, this is no longer the case by default because most of the time you're using a tooling chain that takes care of it in other ways (like SvelteKit). If you need CSS to be returned from `render`, you can set the `css` compiler option to `'injected'` and it will add `