diff --git a/apps/svelte.dev/.gitignore b/apps/svelte.dev/.gitignore
index 321615eddf..82cbd2da73 100644
--- a/apps/svelte.dev/.gitignore
+++ b/apps/svelte.dev/.gitignore
@@ -6,6 +6,8 @@
/src/routes/_home/Supporters/contributors.js
/src/routes/_home/Supporters/donors.jpg
/src/routes/_home/Supporters/donors.js
+/scripts/svelte-template
+/static/svelte-template.json
# git-repositories of synced docs go here
/repos/
diff --git a/apps/svelte.dev/package.json b/apps/svelte.dev/package.json
index 64a7ab86f5..28a7e97e91 100644
--- a/apps/svelte.dev/package.json
+++ b/apps/svelte.dev/package.json
@@ -35,6 +35,7 @@
"ansi-to-html": "^0.7.2",
"base64-js": "^1.5.1",
"cookie": "^0.7.0",
+ "do-not-zip": "^1.0.0",
"d3-geo": "^3.1.0",
"d3-geo-projection": "^4.0.0",
"editor": "workspace:*",
@@ -72,6 +73,7 @@
"prettier-plugin-svelte": "^3.3.2",
"satori": "^0.10.13",
"satori-html": "^0.3.2",
+ "sv": "^0.6.8",
"svelte": "5.14.0",
"svelte-check": "^4.1.1",
"svelte-preprocess": "^6.0.3",
diff --git a/apps/svelte.dev/scripts/get_svelte_template.js b/apps/svelte.dev/scripts/get_svelte_template.js
new file mode 100644
index 0000000000..d525eaa3df
--- /dev/null
+++ b/apps/svelte.dev/scripts/get_svelte_template.js
@@ -0,0 +1,86 @@
+// @ts-check
+import { readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
+import { join } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { create } from 'sv';
+
+// This download the currente Vite template from Github, adjusts it to our needs, and saves it to static/svelte-template.json
+// This is used by the Svelte REPL as part of the "download project" feature
+
+const force = process.env.FORCE_UPDATE === 'true';
+const output_file = fileURLToPath(new URL('../static/svelte-template.json', import.meta.url));
+const output_dir = fileURLToPath(new URL('./svelte-template', import.meta.url));
+
+try {
+ if (!force && statSync(output_file)) {
+ console.info(`[update/template] ${output_file} exists. Skipping`);
+ process.exit(0);
+ }
+} catch {
+ // create Svelte-Kit skelton app
+ create(output_dir, { template: 'minimal', types: 'typescript', name: 'your-app' });
+
+ function get_all_files(dir) {
+ const files = [];
+ const items = readdirSync(dir, { withFileTypes: true });
+
+ for (const item of items) {
+ const full_path = join(dir, item.name);
+ if (item.isDirectory()) {
+ files.push(...get_all_files(full_path));
+ } else {
+ files.push(full_path.replaceAll('\\', '/'));
+ }
+ }
+
+ return files;
+ }
+
+ const all_files = get_all_files(output_dir);
+ const files = [];
+
+ for (let path of all_files) {
+ const bytes = readFileSync(path);
+ const string = bytes.toString();
+ let data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes];
+
+ if (path.endsWith('routes/+page.svelte')) {
+ data = `\n\n\n`;
+ }
+
+ files.push({ path: path.slice(output_dir.length + 1), data });
+ }
+
+ files.push({
+ path: 'src/routes/+page.js',
+ data:
+ "// Because we don't know whether or not your playground app can run in a server environment, we disable server-side rendering.\n" +
+ '// Make sure to test whether or not you can re-enable it, as SSR improves perceived performance and site accessibility.\n' +
+ '// Read more about this option here: https://svelte.dev/docs/kit/page-options#ssr\n' +
+ 'export const ssr = false;\n'
+ });
+
+ // add CSS styles from playground to the project
+ const html = readFileSync(
+ join(output_dir, '../../../../packages/repl/src/lib/Output/srcdoc/index.html'),
+ { encoding: 'utf-8' }
+ );
+ const css = html
+ .slice(html.indexOf(''))
+ .split('\n')
+ .map((line) =>
+ // remove leading \t
+ line.slice(3)
+ )
+ .join('\n')
+ .trimStart();
+ files.push({
+ path: 'src/app.css',
+ data: css
+ });
+
+ writeFileSync(output_file, JSON.stringify(files));
+
+ // remove output dir afterwards to prevent it messing with Vite watcher
+ rmSync(output_dir, { force: true, recursive: true });
+}
diff --git a/apps/svelte.dev/scripts/update.js b/apps/svelte.dev/scripts/update.js
index 41a4c2e9b6..9c25d958dc 100644
--- a/apps/svelte.dev/scripts/update.js
+++ b/apps/svelte.dev/scripts/update.js
@@ -9,3 +9,4 @@ const env = {
fork(`${dir}/get_contributors.js`, { env });
fork(`${dir}/get_donors.js`, { env });
+fork(`${dir}/get_svelte_template.js`, { env });
diff --git a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte
index f883a1ec62..51f0c2b51a 100644
--- a/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte
+++ b/apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte
@@ -1,4 +1,6 @@