diff --git a/.circleci/config.yml b/.circleci/config.yml
index dac362b5530b..6db12bf41959 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -614,22 +614,22 @@ workflows:
           requires:
             - build
       - create-sandboxes:
-          parallelism: 35
+          parallelism: 36
           requires:
             - build
       # - smoke-test-sandboxes: # disabled for now
       #     requires:
       #       - create-sandboxes
       - build-sandboxes:
-          parallelism: 35
+          parallelism: 36
           requires:
             - create-sandboxes
       - chromatic-sandboxes:
-          parallelism: 32
+          parallelism: 33
           requires:
             - build-sandboxes
       - e2e-production:
-          parallelism: 30
+          parallelism: 31
           requires:
             - build-sandboxes
       - e2e-dev:
@@ -637,7 +637,7 @@ workflows:
           requires:
             - create-sandboxes
       - test-runner-production:
-          parallelism: 30
+          parallelism: 31
           requires:
             - build-sandboxes
       # TODO: reenable once we find out the source of flakyness
diff --git a/code/e2e-tests/addon-actions.spec.ts b/code/e2e-tests/addon-actions.spec.ts
index 520c2b5dc41f..a9f32e61c022 100644
--- a/code/e2e-tests/addon-actions.spec.ts
+++ b/code/e2e-tests/addon-actions.spec.ts
@@ -3,9 +3,16 @@ import process from 'process';
 import { SbPage } from './util';
 
 const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001';
+const templateName = process.env.STORYBOOK_TEMPLATE_NAME || '';
 
 test.describe('addon-actions', () => {
   test('should trigger an action', async ({ page }) => {
+    // eslint-disable-next-line jest/no-disabled-tests
+    test.skip(
+      // eslint-disable-next-line jest/valid-title
+      templateName.includes('svelte') && templateName.includes('prerelease'),
+      'Svelte 5 prerelase does not support automatic actions with our current example components yet'
+    );
     await page.goto(storybookUrl);
     const sbPage = new SbPage(page);
     sbPage.waitUntilLoaded();
diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json
index 585a77752bed..4cfe87214037 100644
--- a/code/frameworks/svelte-vite/package.json
+++ b/code/frameworks/svelte-vite/package.json
@@ -52,18 +52,18 @@
     "@storybook/svelte": "workspace:*",
     "@sveltejs/vite-plugin-svelte": "^2.4.2",
     "magic-string": "^0.30.0",
-    "svelte-preprocess": "^5.0.4",
+    "svelte-preprocess": "^5.1.1",
     "sveltedoc-parser": "^4.2.1",
     "ts-dedent": "^2.2.0"
   },
   "devDependencies": {
     "@types/node": "^18.0.0",
-    "svelte": "^4.0.0",
+    "svelte": "^5.0.0-next.16",
     "typescript": "^5.3.2",
     "vite": "^4.0.0"
   },
   "peerDependencies": {
-    "svelte": "^3.0.0 || ^4.0.0",
+    "svelte": "^4.0.0 || ^5.0.0-next.16",
     "vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
   },
   "engines": {
diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json
index 9e47d3bb34ee..4885a726417b 100644
--- a/code/frameworks/svelte-webpack5/package.json
+++ b/code/frameworks/svelte-webpack5/package.json
@@ -59,7 +59,7 @@
   },
   "peerDependencies": {
     "@babel/core": "*",
-    "svelte": "^3.48.0 || ^4.0.0",
+    "svelte": "^4.0.0 || ^5.0.0-next.16",
     "svelte-loader": "*"
   },
   "engines": {
diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json
index f952e2515b07..162fb8229411 100644
--- a/code/frameworks/sveltekit/package.json
+++ b/code/frameworks/sveltekit/package.json
@@ -64,7 +64,7 @@
     "vite": "^4.0.0"
   },
   "peerDependencies": {
-    "svelte": "^3.0.0 || ^4.0.0",
+    "svelte": "^4.0.0 || ^5.0.0-next.16",
     "vite": "^4.0.0"
   },
   "engines": {
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte
new file mode 100644
index 000000000000..cd00f38a3d57
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte
@@ -0,0 +1,38 @@
+<script lang="ts">
+  /**
+   * @component Button TypeScript
+   * @wrapper
+   */
+  import { global as globalThis } from '@storybook/global';
+  // @ts-ignore
+  const Button = globalThis.Components?.Button;
+
+  /**
+   * Rounds the button
+   */
+  export let primary: boolean = false;
+
+  /**
+   * Displays the count
+   */
+  export let count: number = 0;
+
+  /**
+   * Button text
+   * @slot
+   */
+  export let text: string = 'You clicked';
+
+  function handleClick(_event: MouseEvent) {
+    count += 1;
+  }
+</script>
+
+<h1>Button TypeScript</h1>
+
+<Button {primary} on:click on:click={handleClick} label="{text}: {count}" />
+
+<p>A little text to show this is a view.</p>
+<p>If we need to test components in a Svelte environment, for instance to test slot behaviour,</p>
+<p>then wrapping the component up in a view</p>
+<p>made just for the story is the simplest way to achieve this.</p>
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Forms.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Forms.svelte
new file mode 100644
index 000000000000..371a17656bea
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Forms.svelte
@@ -0,0 +1,7 @@
+<script>
+	import { enhance } from '$app/forms';
+</script>
+
+<form use:enhance>
+	<button>enhance</button>
+</form>
\ No newline at end of file
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte
new file mode 100644
index 000000000000..4e7d69e0e051
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte
@@ -0,0 +1,8 @@
+<ul>
+  <li><a href="/basic-href">Link to <code>/basic-href</code></a></li>
+  <li>
+    <a href="/deep/nested/link?with=true&multiple-params=200#and-an-id"
+      >Link to <code>/deep/nested/link?with=true&multiple-params=200#and-an-id</code></a
+    >
+  </li>
+</ul>
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte
new file mode 100644
index 000000000000..4bcb7d0e6fc9
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte
@@ -0,0 +1,25 @@
+<script>
+	import { goto, invalidate, invalidateAll, afterNavigate } from '$app/navigation';
+
+	export let afterNavigateFn;
+
+	afterNavigate(afterNavigateFn);
+</script>
+
+<button
+	on:click={() => {
+		goto('/storybook-goto');
+	}}>goto</button
+>
+
+<button
+	on:click={() => {
+		invalidate('/storybook-invalidate');
+	}}>invalidate</button
+>
+
+<button
+	on:click={() => {
+		invalidateAll();
+	}}>invalidateAll</button
+>
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte
new file mode 100644
index 000000000000..164b00f7fa8b
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte
@@ -0,0 +1,17 @@
+<script>
+	import { page, navigating, updated, getStores } from '$app/stores';
+
+	let { navigating: navigatingStore, page: pageStore, updated: updatedStore } = getStores();
+
+	updated.check();
+</script>
+
+<p>Directly importing</p>
+<pre>{JSON.stringify($page, null, 2)}</pre>
+<pre>{JSON.stringify($navigating, null, 2)}</pre>
+<pre>{JSON.stringify($updated, null, 2)}</pre>
+
+<p>With getStores</p>
+<pre>{JSON.stringify($pageStore, null, 2)}</pre>
+<pre>{JSON.stringify($navigatingStore, null, 2)}</pre>
+<pre>{JSON.stringify($updatedStore, null, 2)}</pre>
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js
new file mode 100644
index 000000000000..72b584baef76
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js
@@ -0,0 +1,26 @@
+import { expect, fn, within } from '@storybook/test';
+import Forms from './Forms.svelte';
+
+export default {
+  title: 'stories/sveltekit/modules/forms',
+  component: Forms,
+  tags: ['autodocs'],
+};
+
+const enhance = fn();
+
+export const Enhance = {
+  async play({ canvasElement }) {
+    const canvas = within(canvasElement);
+    const button = canvas.getByText('enhance');
+    button.click();
+    expect(enhance).toHaveBeenCalled();
+  },
+  parameters: {
+    sveltekit_experimental: {
+      forms: {
+        enhance,
+      },
+    },
+  },
+};
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js
new file mode 100644
index 000000000000..f1cbf4973534
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js
@@ -0,0 +1,53 @@
+import { expect, fn, within } from '@storybook/test';
+import Hrefs from './Hrefs.svelte';
+
+export default {
+  title: 'stories/sveltekit/modules/hrefs',
+  component: Hrefs,
+  tags: ['autodocs'],
+};
+
+export const DefaultActions = {
+  async play({ canvasElement }) {
+    const canvas = within(canvasElement);
+    // eslint-disable-next-line no-undef
+    const initialUrl = window.location.toString();
+
+    const basicHref = canvas.getByText('/basic-href');
+    basicHref.click();
+
+    const complexHref = canvas.getByText(
+      '/deep/nested/link?with=true&multiple-params=200#and-an-id'
+    );
+    complexHref.click();
+
+    // eslint-disable-next-line no-undef
+    const finalUrl = window.location.toString();
+    expect(finalUrl).toBe(initialUrl);
+  },
+};
+
+const basicStringMatch = fn();
+const noMatch = fn();
+const exactStringMatch = fn();
+const regexMatch = fn();
+
+export const Callbacks = {
+  parameters: {
+    sveltekit_experimental: {
+      hrefs: {
+        '/basic-href': basicStringMatch,
+        '/basic': noMatch,
+        '/deep/nested/link?with=true&multiple-params=200#and-an-id': exactStringMatch,
+        'nested/link\\?with': { callback: regexMatch, asRegex: true },
+      },
+    },
+  },
+  play: async (ctx) => {
+    await DefaultActions.play(ctx);
+    expect(basicStringMatch).toHaveBeenCalledTimes(1);
+    expect(noMatch).not.toHaveBeenCalled();
+    expect(exactStringMatch).toHaveBeenCalledTimes(1);
+    expect(regexMatch).toHaveBeenCalledTimes(1);
+  },
+};
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js
new file mode 100644
index 000000000000..ded12268e03c
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js
@@ -0,0 +1,84 @@
+import { expect, fn, within } from '@storybook/test';
+import Navigation from './Navigation.svelte';
+
+export default {
+  title: 'stories/sveltekit/modules/navigation',
+  component: Navigation,
+  tags: ['autodocs'],
+};
+
+const goto = fn();
+
+export const Goto = {
+  async play({ canvasElement }) {
+    const canvas = within(canvasElement);
+    const button = canvas.getByText('goto');
+    button.click();
+    expect(goto).toHaveBeenCalledWith('/storybook-goto');
+  },
+  parameters: {
+    sveltekit_experimental: {
+      navigation: {
+        goto,
+      },
+    },
+  },
+};
+
+export const DefaultActions = {};
+
+const invalidate = fn();
+
+export const Invalidate = {
+  async play({ canvasElement }) {
+    const canvas = within(canvasElement);
+    const button = canvas.getByText('invalidate', { exact: true });
+    button.click();
+    expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate');
+  },
+  parameters: {
+    sveltekit_experimental: {
+      navigation: {
+        invalidate,
+      },
+    },
+  },
+};
+
+const invalidateAll = fn();
+
+export const InvalidateAll = {
+  async play({ canvasElement }) {
+    const canvas = within(canvasElement);
+    const button = canvas.getByText('invalidateAll');
+    button.click();
+    expect(invalidateAll).toHaveBeenCalledWith();
+  },
+  parameters: {
+    sveltekit_experimental: {
+      navigation: {
+        invalidateAll,
+      },
+    },
+  },
+};
+
+const afterNavigateFn = fn();
+
+export const AfterNavigate = {
+  async play() {
+    expect(afterNavigateFn).toHaveBeenCalledWith({ test: 'passed' });
+  },
+  args: {
+    afterNavigateFn,
+  },
+  parameters: {
+    sveltekit_experimental: {
+      navigation: {
+        afterNavigate: {
+          test: 'passed',
+        },
+      },
+    },
+  },
+};
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js
new file mode 100644
index 000000000000..7f7401cf8bee
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js
@@ -0,0 +1,116 @@
+import Stores from './Stores.svelte';
+
+export default {
+  title: 'stories/sveltekit/modules/stores',
+  component: Stores,
+  tags: ['autodocs'],
+};
+
+export const AllUndefined = {};
+
+export const PageStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        page: {
+          data: {
+            test: 'passed',
+          },
+        },
+      },
+    },
+  },
+};
+
+export const NavigatingStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        navigating: {
+          route: {
+            id: '/storybook',
+          },
+        },
+      },
+    },
+  },
+};
+
+export const UpdatedStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        updated: true,
+      },
+    },
+  },
+};
+
+export const PageAndNavigatingStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        page: {
+          data: {
+            test: 'passed',
+          },
+        },
+        navigating: {
+          route: {
+            id: '/storybook',
+          },
+        },
+      },
+    },
+  },
+};
+
+export const PageAndUpdatedStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        page: {
+          data: {
+            test: 'passed',
+          },
+        },
+        updated: true,
+      },
+    },
+  },
+};
+
+export const NavigatingAndUpdatedStore = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        navigating: {
+          route: {
+            id: '/storybook',
+          },
+        },
+        updated: true,
+      },
+    },
+  },
+};
+
+export const AllThreeStores = {
+  parameters: {
+    sveltekit_experimental: {
+      stores: {
+        page: {
+          data: {
+            test: 'passed',
+          },
+        },
+        navigating: {
+          route: {
+            id: '/storybook',
+          },
+        },
+        updated: true,
+      },
+    },
+  },
+};
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js
new file mode 100644
index 000000000000..f33428810ee9
--- /dev/null
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js
@@ -0,0 +1,12 @@
+import ButtonTypescript from './ButtonTypeScript.svelte';
+
+export default {
+  title: 'stories/renderers/svelte/ts-docs',
+  component: ButtonTypescript,
+  args: {
+    primary: true,
+  },
+  tags: ['autodocs'],
+};
+
+export const Primary = {};
diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts
index 6aeed1d585a3..1399da6bcef9 100644
--- a/code/lib/cli/src/sandbox-templates.ts
+++ b/code/lib/cli/src/sandbox-templates.ts
@@ -376,6 +376,17 @@ const baseTemplates = {
     },
     skipTasks: ['e2e-tests-dev', 'bench'],
   },
+  'svelte-kit/prerelease-ts': {
+    name: 'SvelteKit Prerelease (Vite | TypeScript)',
+    script:
+      'yarn create svelte-with-args --name=svelte-kit/prerelease-ts --directory={{beforeDir}} --template=skeleton --types=typescript --no-prettier --no-eslint --no-playwright --no-vitest --svelte5',
+    expected: {
+      framework: '@storybook/sveltekit',
+      renderer: '@storybook/svelte',
+      builder: '@storybook/builder-vite',
+    },
+    skipTasks: ['e2e-tests-dev', 'bench'],
+  },
   'lit-vite/default-js': {
     name: 'Lit Latest (Vite | JavaScript)',
     script:
@@ -619,6 +630,7 @@ export const daily: TemplateKey[] = [
   'vue-cli/default-js',
   'lit-vite/default-js',
   'svelte-kit/skeleton-js',
+  'svelte-kit/prerelease-ts',
   'svelte-vite/default-js',
   'nextjs/13-ts',
   'nextjs/default-js',
diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json
index fca64af0725c..2792fa28bc32 100644
--- a/code/presets/svelte-webpack/package.json
+++ b/code/presets/svelte-webpack/package.json
@@ -76,7 +76,7 @@
   },
   "peerDependencies": {
     "@babel/core": "*",
-    "svelte": "^3.1.0 || ^4.0.0",
+    "svelte": "^4.0.0 || ^5.0.0-next.16",
     "svelte-loader": "*"
   },
   "engines": {
diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json
index 74eae303430f..c7b3ad589592 100644
--- a/code/renderers/svelte/package.json
+++ b/code/renderers/svelte/package.json
@@ -63,12 +63,12 @@
   },
   "devDependencies": {
     "expect-type": "^0.15.0",
-    "svelte": "^4.0.0",
-    "svelte-check": "3.4.6",
+    "svelte": "^5.0.0-next.15",
+    "svelte-check": "^3.6.1",
     "typescript": "^5.3.2"
   },
   "peerDependencies": {
-    "svelte": "^3.1.0 || ^4.0.0"
+    "svelte": "^4.0.0 || ^5.0.0-next.16"
   },
   "engines": {
     "node": ">=16.0.0"
diff --git a/code/renderers/svelte/src/render.ts b/code/renderers/svelte/src/render.ts
index cfde36047fa1..b1821b692358 100644
--- a/code/renderers/svelte/src/render.ts
+++ b/code/renderers/svelte/src/render.ts
@@ -1,6 +1,5 @@
 /* eslint-disable no-param-reassign */
 import type { RenderContext, ArgsStoryFn } from '@storybook/types';
-import type { SvelteComponentTyped } from 'svelte';
 import { RESET_STORY_ARGS } from '@storybook/core-events';
 // ! DO NOT change this PreviewRender import to a relative path, it will break it.
 // ! A relative import will be compiled at build time, and Svelte will be unable to
@@ -10,10 +9,14 @@ import { RESET_STORY_ARGS } from '@storybook/core-events';
 // eslint-disable-next-line import/no-extraneous-dependencies
 import PreviewRender from '@storybook/svelte/templates/PreviewRender.svelte';
 import { addons } from '@storybook/preview-api';
+import * as svelte from 'svelte';
 
 import type { SvelteRenderer } from './types';
 
-const componentsByDomElement = new Map<SvelteRenderer['canvasElement'], SvelteComponentTyped>();
+const componentsByDomElement = new Map<
+  SvelteRenderer['canvasElement'],
+  any // ReturnType<typeof createRoot | typeof mount> depends on the version of Svelte v4 or v5
+>();
 
 function teardown(canvasElement: SvelteRenderer['canvasElement']) {
   if (!componentsByDomElement.has(canvasElement)) {
@@ -26,6 +29,25 @@ function teardown(canvasElement: SvelteRenderer['canvasElement']) {
   componentsByDomElement.delete(canvasElement);
 }
 
+/**
+ * Mount the PreviewRender component to the provided canvasElement
+ * Either using the Svelte v4 or v5 API
+ */
+function createRoot(target: HTMLElement, props: any) {
+  if ((svelte as any).createRoot) {
+    // Svelte v5
+    return svelte.createRoot(PreviewRender, {
+      target,
+      props,
+    });
+  }
+  // Svelte v4
+  return new (PreviewRender as any)({
+    target,
+    props,
+  });
+}
+
 /**
  * This is a workaround for the issue that when resetting args,
  * the story needs to be remounted completely to revert to the component's default props.
@@ -66,16 +88,13 @@ export function renderToCanvas(
   }
 
   if (!existingComponent || remount) {
-    const createdComponent = new PreviewRender({
-      target: canvasElement,
-      props: {
-        storyFn,
-        storyContext,
-        name,
-        kind,
-        showError,
-      },
-    }) as SvelteComponentTyped;
+    const createdComponent = createRoot(canvasElement, {
+      storyFn,
+      storyContext,
+      name,
+      kind,
+      showError,
+    });
     componentsByDomElement.set(canvasElement, createdComponent);
   } else {
     existingComponent.$set({
diff --git a/code/renderers/svelte/src/typings.d.ts b/code/renderers/svelte/src/typings.d.ts
index 109dcd62da0e..2e00d983aa34 100644
--- a/code/renderers/svelte/src/typings.d.ts
+++ b/code/renderers/svelte/src/typings.d.ts
@@ -1,2 +1,9 @@
 declare var STORYBOOK_ENV: 'svelte';
 declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined;
+
+declare module '*.svelte' {
+  import type { ComponentType } from 'svelte';
+
+  const component: ComponentType;
+  export default component;
+}
diff --git a/code/renderers/svelte/templates/SlotDecorator.svelte b/code/renderers/svelte/templates/SlotDecorator.svelte
index 5bd0fdfe3455..9de64db04c3d 100644
--- a/code/renderers/svelte/templates/SlotDecorator.svelte
+++ b/code/renderers/svelte/templates/SlotDecorator.svelte
@@ -5,19 +5,19 @@
   export let Component;
   export let props = {};
   export let on = undefined;
-
+  
   let instance;
   let decoratorInstance;
-
-  function getInstance() {
-    // instance can be undefined if a decorator doesn't have <slot/>
-    return instance || decoratorInstance;
-  }
-
+  
   if (on) {
-    // Attach svelte event listeners.
-    Object.keys(on).forEach((eventName) => {
-      onMount(() => getInstance().$on(eventName, on[eventName]));
+    // Attach Svelte event listeners in Svelte v4
+    // In Svelte v5 this is not possible anymore as instances are no longer classes with $on() properties, so it will be a no-op
+    onMount(() => {
+      Object.entries(on).forEach(([eventName, eventCallback]) => {
+        // instance can be undefined if a decorator doesn't have <slot/>
+        const inst = instance ?? decoratorInstance;
+        inst?.$on?.(eventName, eventCallback)
+      });
     });
   }
 </script>
diff --git a/code/yarn.lock b/code/yarn.lock
index 551e676483a2..264293e08cea 100644
--- a/code/yarn.lock
+++ b/code/yarn.lock
@@ -6201,7 +6201,7 @@ __metadata:
     typescript: "npm:^5.3.2"
   peerDependencies:
     "@babel/core": "*"
-    svelte: ^3.1.0 || ^4.0.0
+    svelte: ^4.0.0 || ^5.0.0-next.16
     svelte-loader: "*"
   languageName: unknown
   linkType: soft
@@ -6679,14 +6679,14 @@ __metadata:
     "@sveltejs/vite-plugin-svelte": "npm:^2.4.2"
     "@types/node": "npm:^18.0.0"
     magic-string: "npm:^0.30.0"
-    svelte: "npm:^4.0.0"
-    svelte-preprocess: "npm:^5.0.4"
+    svelte: "npm:^5.0.0-next.16"
+    svelte-preprocess: "npm:^5.1.1"
     sveltedoc-parser: "npm:^4.2.1"
     ts-dedent: "npm:^2.2.0"
     typescript: "npm:^5.3.2"
     vite: "npm:^4.0.0"
   peerDependencies:
-    svelte: ^3.0.0 || ^4.0.0
+    svelte: ^4.0.0 || ^5.0.0-next.16
     vite: ^3.0.0 || ^4.0.0 || ^5.0.0
   languageName: unknown
   linkType: soft
@@ -6704,7 +6704,7 @@ __metadata:
     typescript: "npm:^5.3.2"
   peerDependencies:
     "@babel/core": "*"
-    svelte: ^3.48.0 || ^4.0.0
+    svelte: ^4.0.0 || ^5.0.0-next.16
     svelte-loader: "*"
   languageName: unknown
   linkType: soft
@@ -6720,14 +6720,14 @@ __metadata:
     "@storybook/preview-api": "workspace:*"
     "@storybook/types": "workspace:*"
     expect-type: "npm:^0.15.0"
-    svelte: "npm:^4.0.0"
-    svelte-check: "npm:3.4.6"
+    svelte: "npm:^5.0.0-next.15"
+    svelte-check: "npm:^3.6.1"
     sveltedoc-parser: "npm:^4.2.1"
     ts-dedent: "npm:^2.0.0"
     type-fest: "npm:~2.19"
     typescript: "npm:^5.3.2"
   peerDependencies:
-    svelte: ^3.1.0 || ^4.0.0
+    svelte: ^4.0.0 || ^5.0.0-next.16
   languageName: unknown
   linkType: soft
 
@@ -6743,7 +6743,7 @@ __metadata:
     typescript: "npm:^5.3.2"
     vite: "npm:^4.0.0"
   peerDependencies:
-    svelte: ^3.0.0 || ^4.0.0
+    svelte: ^4.0.0 || ^5.0.0-next.16
     vite: ^4.0.0
   languageName: unknown
   linkType: soft
@@ -9482,6 +9482,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"acorn-typescript@npm:^1.4.11":
+  version: 1.4.12
+  resolution: "acorn-typescript@npm:1.4.12"
+  peerDependencies:
+    acorn: ">=8.9.0"
+  checksum: a3b33ed0dc321e3364da507a3decec96423736384068c88fea5ea57aeae864ea115a6c4a20b3ace71b75f4901b0657bec82d83aab30a8ad0dfc4bfc0d8337546
+  languageName: node
+  linkType: hard
+
 "acorn-walk@npm:^7.2.0":
   version: 7.2.0
   resolution: "acorn-walk@npm:7.2.0"
@@ -10256,6 +10265,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"axobject-query@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "axobject-query@npm:4.0.0"
+  dependencies:
+    dequal: "npm:^2.0.3"
+  checksum: 4d756b5c2ff099f1c7f99e55a5de9b2066cb2a13a3170185ff34bfec2d7bcab81eb820a4e7340d35c251341b61ebee6e705b7ce64db78224df1df5a4d68448fe
+  languageName: node
+  linkType: hard
+
 "b4a@npm:^1.6.4":
   version: 1.6.4
   resolution: "b4a@npm:1.6.4"
@@ -14802,6 +14820,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esm-env@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "esm-env@npm:1.0.0"
+  checksum: 6ea0001410224ebc18de4a83ce97dbdca6abc83ea4bbe91625aa3aead70793bb98dfa089f38e2cc5c13b7b025668d0649d5e25f2f9e8cca0f4aa3ad3406870d0
+  languageName: node
+  linkType: hard
+
 "espree@npm:9.2.0":
   version: 9.2.0
   resolution: "espree@npm:9.2.0"
@@ -14843,6 +14868,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esrap@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "esrap@npm:1.2.1"
+  dependencies:
+    "@jridgewell/sourcemap-codec": "npm:^1.4.15"
+    "@types/estree": "npm:^1.0.1"
+  checksum: 28d6e36adcf4342a844a938a736132269c33e9db6bbefc98c6af5ed06c14899afcc85391e7ce4824ce5066877fa10b0ed5c5007592cbc58012be95f13c66467f
+  languageName: node
+  linkType: hard
+
 "esrecurse@npm:^4.3.0":
   version: 4.3.0
   resolution: "esrecurse@npm:4.3.0"
@@ -27215,9 +27250,9 @@ __metadata:
   languageName: node
   linkType: hard
 
-"svelte-check@npm:3.4.6":
-  version: 3.4.6
-  resolution: "svelte-check@npm:3.4.6"
+"svelte-check@npm:^3.6.1":
+  version: 3.6.2
+  resolution: "svelte-check@npm:3.6.2"
   dependencies:
     "@jridgewell/trace-mapping": "npm:^0.3.17"
     chokidar: "npm:^3.4.1"
@@ -27225,13 +27260,13 @@ __metadata:
     import-fresh: "npm:^3.2.1"
     picocolors: "npm:^1.0.0"
     sade: "npm:^1.7.4"
-    svelte-preprocess: "npm:^5.0.4"
+    svelte-preprocess: "npm:^5.1.0"
     typescript: "npm:^5.0.3"
   peerDependencies:
-    svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0
+    svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0
   bin:
     svelte-check: bin/svelte-check
-  checksum: 7f537831af8f2c47859ca72f4a929d24c58f2946f949f7c9721351be97ff9d0674c57db003e3ad3883fdd85761b7950c5c11513c2a917c91091f155e2d026350
+  checksum: 3f389df29268d4df9b561d0b206566e827af84923c70150b2dadfd407bcbdaccbfd561bd8b93884597de62477d62826ff1a5108854641078b692130441a49a55
   languageName: node
   linkType: hard
 
@@ -27273,7 +27308,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"svelte-preprocess@npm:^5.0.4":
+"svelte-preprocess@npm:^5.1.0, svelte-preprocess@npm:^5.1.1":
   version: 5.1.1
   resolution: "svelte-preprocess@npm:5.1.1"
   dependencies:
@@ -27340,6 +27375,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"svelte@npm:^5.0.0-next.15, svelte@npm:^5.0.0-next.16":
+  version: 5.0.0-next.19
+  resolution: "svelte@npm:5.0.0-next.19"
+  dependencies:
+    "@ampproject/remapping": "npm:^2.2.1"
+    "@jridgewell/sourcemap-codec": "npm:^1.4.15"
+    acorn: "npm:^8.10.0"
+    acorn-typescript: "npm:^1.4.11"
+    aria-query: "npm:^5.3.0"
+    axobject-query: "npm:^4.0.0"
+    esm-env: "npm:^1.0.0"
+    esrap: "npm:^1.2.1"
+    is-reference: "npm:^3.0.1"
+    locate-character: "npm:^3.0.0"
+    magic-string: "npm:^0.30.4"
+    zimmerframe: "npm:^1.1.0"
+  checksum: 2efc415d3a51cd9094349aa0295e728ea74e10bad17dedd167b1fae64de8ee5d46cbd27b5cfb152e4af641e1326e233dfeb918d8fa0541f65cf149b85d00419a
+  languageName: node
+  linkType: hard
+
 "sveltedoc-parser@npm:^4.2.1":
   version: 4.3.1
   resolution: "sveltedoc-parser@npm:4.3.1"
@@ -30221,6 +30276,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"zimmerframe@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "zimmerframe@npm:1.1.0"
+  checksum: dffe3f555bb000176ed9c7577e0fb0c3eddeceb6df9bb3ff870995bac3a51b40fab5443bd3dc47ce91c1f8ecf07282742efb80771ae6a088edc0340bb217f93d
+  languageName: node
+  linkType: hard
+
 "zod@npm:^3.22.2":
   version: 3.22.4
   resolution: "zod@npm:3.22.4"
diff --git a/scripts/task.ts b/scripts/task.ts
index 20dad32716c3..1247cc89351a 100644
--- a/scripts/task.ts
+++ b/scripts/task.ts
@@ -496,7 +496,7 @@ async function run() {
           controller.abort();
         });
 
-        return 1;
+        throw err;
       }
       statuses.set(task, task.service ? 'serving' : 'complete');
 
diff --git a/scripts/tasks/generate.ts b/scripts/tasks/generate.ts
index cbce6c66a1c5..f453fc3222e8 100644
--- a/scripts/tasks/generate.ts
+++ b/scripts/tasks/generate.ts
@@ -1,3 +1,4 @@
+/* eslint-disable import/extensions */
 import { pathExists, remove } from 'fs-extra';
 import { join } from 'path';
 import { REPROS_DIRECTORY } from '../utils/constants';
@@ -27,7 +28,8 @@ export const generate: Task = {
     }
 
     // This uses an async import as it depends on `lib/cli` which requires `code` to be installed.
-    const { generate: generateRepro } = await import('../sandbox/generate');
+    // @ts-expect-error Default import required for dynamic import processed by esbuild
+    const { generate: generateRepro } = (await import('../sandbox/generate.ts')).default;
 
     await generateRepro({
       templates: [details.key],
diff --git a/scripts/tasks/sandbox-parts.ts b/scripts/tasks/sandbox-parts.ts
index d2f5748ce104..d35edced9abc 100644
--- a/scripts/tasks/sandbox-parts.ts
+++ b/scripts/tasks/sandbox-parts.ts
@@ -39,6 +39,7 @@ import { JsPackageManagerFactory } from '../../code/lib/cli/src/js-package-manag
 import { workspacePath } from '../utils/workspace';
 import { babelParse } from '../../code/lib/csf-tools/src/babelParse';
 import { CODE_DIRECTORY, REPROS_DIRECTORY } from '../utils/constants';
+import type { TemplateKey } from '../../code/lib/cli/src/sandbox-templates';
 
 const logger = console;
 
@@ -75,7 +76,7 @@ export const create: Task['run'] = async ({ key, template, sandboxDir }, { dryRu
   }
 };
 
-export const install: Task['run'] = async ({ sandboxDir }, { link, dryRun, debug }) => {
+export const install: Task['run'] = async ({ sandboxDir, key }, { link, dryRun, debug }) => {
   const cwd = sandboxDir;
   await installYarn2({ cwd, dryRun, debug });
 
@@ -93,24 +94,22 @@ export const install: Task['run'] = async ({ sandboxDir }, { link, dryRun, debug
     // of any storybook packages as verdaccio is not able to both proxy to npm and publish over
     // the top. In theory this could mask issues where different versions cause problems.
     await addPackageResolutions({ cwd, dryRun, debug });
-    await configureYarn2ForVerdaccio({ cwd, dryRun, debug });
+    await configureYarn2ForVerdaccio({ cwd, dryRun, debug, key });
 
     // Add vite plugin workarounds for frameworks that need it
     // (to support vite 5 without peer dep errors)
-    if (
-      [
-        'bench-react-vite-default-ts',
-        'bench-react-vite-default-ts-nodocs',
-        'bench-react-vite-default-ts-test-build',
-        'internal-ssv6-vite',
-        'react-vite-default-js',
-        'react-vite-default-ts',
-        'svelte-vite-default-js',
-        'svelte-vite-default-ts',
-        'vue3-vite-default-js',
-        'vue3-vite-default-ts',
-      ].includes(sandboxDir.split(sep).at(-1))
-    ) {
+    const sandboxesNeedingWorkarounds: TemplateKey[] = [
+      'bench/react-vite-default-ts',
+      'bench/react-vite-default-ts-nodocs',
+      'bench/react-vite-default-ts-test-build',
+      'react-vite/default-js',
+      'react-vite/default-ts',
+      'svelte-vite/default-js',
+      'svelte-vite/default-ts',
+      'vue3-vite/default-js',
+      'vue3-vite/default-ts',
+    ];
+    if (sandboxesNeedingWorkarounds.includes(key)) {
       await addWorkaroundResolutions({ cwd, dryRun, debug });
     }
 
diff --git a/scripts/utils/yarn.ts b/scripts/utils/yarn.ts
index 19f87d1c0182..2f1fdc8b838e 100644
--- a/scripts/utils/yarn.ts
+++ b/scripts/utils/yarn.ts
@@ -1,6 +1,7 @@
 import { pathExists, readJSON, writeJSON } from 'fs-extra';
 import path from 'path';
 
+import type { TemplateKey } from 'get-template';
 import { exec } from './exec';
 // TODO -- should we generate this file a second time outside of CLI?
 import storybookVersions from '../../code/lib/cli/src/versions';
@@ -75,7 +76,12 @@ export const addWorkaroundResolutions = async ({ cwd, dryRun }: YarnOptions) =>
   await writeJSON(packageJsonPath, packageJson, { spaces: 2 });
 };
 
-export const configureYarn2ForVerdaccio = async ({ cwd, dryRun, debug }: YarnOptions) => {
+export const configureYarn2ForVerdaccio = async ({
+  cwd,
+  dryRun,
+  debug,
+  key,
+}: YarnOptions & { key: TemplateKey }) => {
   const command = [
     // We don't want to use the cache or we might get older copies of our built packages
     // (with identical versions), as yarn (correctly I guess) assumes the same version hasn't changed
@@ -89,10 +95,20 @@ export const configureYarn2ForVerdaccio = async ({ cwd, dryRun, debug }: YarnOpt
     `yarn config set pnpFallbackMode none`,
     // We need to be able to update lockfile when bootstrapping the examples
     `yarn config set enableImmutableInstalls false`,
+  ];
+
+  if (key === 'svelte-kit/prerelease-ts') {
+    // Don't error with INCOMPATIBLE_PEER_DEPENDENCY for SvelteKit prerelease, it is expected
+    command.push(
+      `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" } ]'`
+    );
+  } else {
     // Discard all YN0013 - FETCH_NOT_CACHED messages
     // Error on YN0060 - INCOMPATIBLE_PEER_DEPENDENCY
-    `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" }, { "code": "YN0060", "level": "error" } ]'`,
-  ];
+    command.push(
+      `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" }, { "code": "YN0060", "level": "error" } ]'`
+    );
+  }
 
   await exec(
     command,