From b7b365780ab0f0134c9c16fd524f494e536b08c5 Mon Sep 17 00:00:00 2001 From: Palcimer Date: Tue, 14 Jul 2026 15:50:42 +0900 Subject: [PATCH 1/6] Add SvelteKit webframework option to fedify init Fedify already ships a SvelteKit integration package and example app, but `fedify init` couldn't scaffold one, so add a `sveltekit` option via `sv create`. https://github.com/fedify-dev/fedify/issues/892 Assisted-by: Claude Code:claude-sonnet-5 --- packages/init/src/const.ts | 1 + .../templates/sveltekit/hooks.server.ts.tpl | 7 +++ packages/init/src/test/action.ts | 2 +- packages/init/src/test/lookup.ts | 1 + packages/init/src/test/port.ts | 9 ++- packages/init/src/types.ts | 2 +- packages/init/src/webframeworks/mod.ts | 2 + packages/init/src/webframeworks/sveltekit.ts | 63 +++++++++++++++++++ 8 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 packages/init/src/templates/sveltekit/hooks.server.ts.tpl create mode 100644 packages/init/src/webframeworks/sveltekit.ts diff --git a/packages/init/src/const.ts b/packages/init/src/const.ts index b4120a80d..af5cc2e71 100644 --- a/packages/init/src/const.ts +++ b/packages/init/src/const.ts @@ -15,6 +15,7 @@ export const WEB_FRAMEWORK = [ "express", "nuxt", "solidstart", + "sveltekit", ] as const; /** All supported message queue backend identifiers. */ export const MESSAGE_QUEUE = Object.keys(mq) as readonly (keyof typeof mq)[]; diff --git a/packages/init/src/templates/sveltekit/hooks.server.ts.tpl b/packages/init/src/templates/sveltekit/hooks.server.ts.tpl new file mode 100644 index 000000000..47a60734e --- /dev/null +++ b/packages/init/src/templates/sveltekit/hooks.server.ts.tpl @@ -0,0 +1,7 @@ +import { fedifyHook } from "@fedify/sveltekit"; +import { sequence } from "@sveltejs/kit/hooks"; +import federation from "$lib/federation"; + +export const handle = sequence( + fedifyHook(federation), +); diff --git a/packages/init/src/test/action.ts b/packages/init/src/test/action.ts index 8b64f7d1f..555dd6d17 100644 --- a/packages/init/src/test/action.ts +++ b/packages/init/src/test/action.ts @@ -1,6 +1,6 @@ import { pipe, tap, when } from "@fxts/core"; -import { set } from "../utils.ts"; import type { TestInitCommand } from "../command.ts"; +import { set } from "../utils.ts"; import { checkRequiredDbs } from "./db.ts"; import { fillEmptyOptions } from "./fill.ts"; import runTests from "./run.ts"; diff --git a/packages/init/src/test/lookup.ts b/packages/init/src/test/lookup.ts index e8ea62acb..a86be4d69 100644 --- a/packages/init/src/test/lookup.ts +++ b/packages/init/src/test/lookup.ts @@ -32,6 +32,7 @@ const BANNED_LOOKUP_REASONS: Record = { "solidstart,deno,*,*": "Error occurred while loading submodules in Deno", "astro,deno,*,*": "Astro doesn't support remote packages in Deno", "nuxt,deno,*,*": "Nuxt doesn't support remote packages in Deno", + "sveltekit,deno,*,*": "SvelteKit doesn't support remote packages in Deno", }; const BANNED_LOOKUP_CASES: LookupCasePattern[] = Object.keys( BANNED_LOOKUP_REASONS, diff --git a/packages/init/src/test/port.ts b/packages/init/src/test/port.ts index a4bde934e..f82f5fb9d 100644 --- a/packages/init/src/test/port.ts +++ b/packages/init/src/test/port.ts @@ -132,9 +132,12 @@ export async function replacePortInApp( return; } - if (wf === "astro") { - // Insert server.port into the Astro config - const configPath = join(dir, "astro.config.ts"); + if (wf === "astro" || wf === "sveltekit") { + // Insert server.port into the Astro or Vite config + const configPath = join( + dir, + wf === "astro" ? "astro.config.ts" : "vite.config.ts", + ); const content = await readFile(configPath, "utf8"); await writeFile( configPath, diff --git a/packages/init/src/types.ts b/packages/init/src/types.ts index 33406f9dd..a88735537 100644 --- a/packages/init/src/types.ts +++ b/packages/init/src/types.ts @@ -11,7 +11,7 @@ import type { RequiredNotNull } from "./utils.ts"; /** Supported package manager identifiers: `"deno"`, `"pnpm"`, `"bun"`, `"yarn"`, `"npm"`. */ export type PackageManager = typeof PACKAGE_MANAGER[number]; -/** Supported web framework identifiers: `"hono"`, `"nitro"`, `"next"`, `"elysia"`, `"astro"`, `"express"`. */ +/** Supported web framework identifiers: `"hono"`, `"nitro"`, `"next"`, `"elysia"`, `"astro"`, `"express"`, `"sveltekit"`. */ export type WebFramework = typeof WEB_FRAMEWORK[number]; /** Supported message queue identifiers: `"denokv"`, `"redis"`, `"postgres"`, `"amqp"`. */ diff --git a/packages/init/src/webframeworks/mod.ts b/packages/init/src/webframeworks/mod.ts index eccde686c..086b1df31 100644 --- a/packages/init/src/webframeworks/mod.ts +++ b/packages/init/src/webframeworks/mod.ts @@ -8,6 +8,7 @@ import next from "./next.ts"; import nitro from "./nitro.ts"; import nuxt from "./nuxt.ts"; import solidstart from "./solidstart.ts"; +import sveltekit from "./sveltekit.ts"; /** * Registry of all supported web framework configurations. @@ -26,6 +27,7 @@ const webFrameworks: WebFrameworks = { nitro, nuxt, solidstart, + sveltekit, } as const; export default webFrameworks; diff --git a/packages/init/src/webframeworks/sveltekit.ts b/packages/init/src/webframeworks/sveltekit.ts new file mode 100644 index 000000000..dc88d52e6 --- /dev/null +++ b/packages/init/src/webframeworks/sveltekit.ts @@ -0,0 +1,63 @@ +import { PACKAGE_MANAGER } from "../const.ts"; +import deps from "../json/deps.json" with { type: "json" }; +import { PACKAGE_VERSION, readTemplate } from "../lib.ts"; +import type { PackageManager, WebFrameworkDescription } from "../types.ts"; +import { defaultDenoDependencies, defaultDevDependencies } from "./const.ts"; +import { getInstruction, getNodeBunDevToolTasks } from "./utils.ts"; + +const sveltekitDescription: WebFrameworkDescription = { + label: "SvelteKit", + packageManagers: PACKAGE_MANAGER, + defaultPort: 5173, + init: async ({ packageManager: pm, testMode }) => ({ + command: Array.from(getInitCommand(pm)), + dependencies: { + "@fedify/sveltekit": PACKAGE_VERSION, + ...(pm === "deno" ? defaultDenoDependencies : {}), + }, + devDependencies: { + ...defaultDevDependencies, + "typescript": deps["npm:typescript"], + "@types/node": deps["npm:@types/node@25"], + }, + federationFile: "src/lib/federation.ts", + loggingFile: "src/lib/logging.ts", + env: testMode ? { HOST: "127.0.0.1" } : {} as Record, + files: { + "src/hooks.server.ts": await readTemplate("sveltekit/hooks.server.ts"), + }, + tasks: getNodeBunDevToolTasks(pm), + instruction: getInstruction(pm, 5173), + }), +}; + +export default sveltekitDescription; + +/** + * Returns the shell command array to scaffold a new SvelteKit project + * in the current directory using the given package manager. + */ +function* getInitCommand(pm: PackageManager) { + yield* getSvelteKitInitCommand(pm); + yield* [ + ".", + "--template", + "minimal", + "--types", + "ts", + "--no-add-ons", + "--no-dir-check", + "--no-download-check", + "--install", + pm, + ]; +} + +const getSvelteKitInitCommand = (pm: PackageManager): string[] => + pm === "bun" + ? ["bunx", "sv", "create"] + : pm === "deno" + ? ["deno", "run", "-A", "npm:sv", "create"] + : pm === "npm" + ? ["npx", "sv", "create"] + : [pm, "dlx", "sv", "create"]; From 2085fd2d95790db4e596f191a509b11241dd4940 Mon Sep 17 00:00:00 2001 From: Palcimer Date: Sat, 25 Jul 2026 17:41:18 +0900 Subject: [PATCH 2/6] List SvelteKit in init README and tutorial https://github.com/fedify-dev/fedify/issues/892 --- docs/tutorial/microblog.md | 1 + packages/init/README.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/tutorial/microblog.md b/docs/tutorial/microblog.md index ff1d72e43..616dc8576 100644 --- a/docs/tutorial/microblog.md +++ b/docs/tutorial/microblog.md @@ -169,6 +169,7 @@ Select *Hono*, *npm*, *in-process*, and *in-memory* in order: Express Nuxt SolidStart + SvelteKit ? Choose the package manager to use diff --git a/packages/init/README.md b/packages/init/README.md index 82d8046c8..beb361081 100644 --- a/packages/init/README.md +++ b/packages/init/README.md @@ -26,7 +26,7 @@ Supported options The initializer supports the following project configurations: - **Web frameworks**: Bare-bones, [Astro], [Elysia], [Express], [Hono], - [Next.js], [Nitro], [Nuxt], [SolidStart] + [Next.js], [Nitro], [Nuxt], [SolidStart], [SvelteKit] - **Package managers**: Deno, pnpm, Bun, Yarn, npm - **Key-value stores**: In-Memory, Deno KV, Redis, PostgreSQL - **Message queues**: In-Process, Deno KV, Redis, PostgreSQL, AMQP @@ -39,6 +39,7 @@ The initializer supports the following project configurations: [Nitro]: https://nitro.build/ [Nuxt]: https://nuxt.com/ [SolidStart]: https://start.solidjs.com/ +[SvelteKit]: https://svelte.dev/ Installation From 24562f34ce4da9a07b021fa743d7b8af8fd28e81 Mon Sep 17 00:00:00 2001 From: Palcimer Date: Sat, 25 Jul 2026 17:44:06 +0900 Subject: [PATCH 3/6] Add @fedify/init changes (SvelteKit support) in CHANGES.md https://github.com/fedify-dev/fedify/issues/892 --- CHANGES.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d86cad0c8..81ecbb541 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -329,12 +329,18 @@ To be released. ### @fedify/init + - Supported [SvelteKit] as a web framework option in `fedify init` [[#892], + [#971] by Jang Hanarae] + - Fixed `fedify init`'s hydration test validation to run `format` before `format:check`, which previously caused the entire test suite to fail when - the package manager is `npm` or `pnpm`: [[#950]] [[#952] by Jang Hanarae] + the package manager is `npm` or `pnpm`: [[#950], [#952] by Jang Hanarae] +[SvelteKit]: https://kit.svelte.dev/ +[#892]: https://github.com/fedify-dev/fedify/issues/892 [#950]: https://github.com/fedify-dev/fedify/issues/950 [#952]: https://github.com/fedify-dev/fedify/pull/952 +[#971]: https://github.com/fedify-dev/fedify/pull/971 Version 2.3.3 @@ -5930,7 +5936,6 @@ Released on November 30, 2024. - Let the `fedify lookup` command take multiple arguments. [[#173], [#186] by PGD] -[SvelteKit]: https://kit.svelte.dev/ [#162]: https://github.com/fedify-dev/fedify/issues/162 [#170]: https://github.com/fedify-dev/fedify/issues/170 [#171]: https://github.com/fedify-dev/fedify/issues/171 From 0f148bca87d15f1fec6a8f293bd05d1d30c3217a Mon Sep 17 00:00:00 2001 From: Palcimer Date: Mon, 27 Jul 2026 13:45:27 +0900 Subject: [PATCH 4/6] Update comments about vars in `types.ts` --- packages/init/src/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/init/src/types.ts b/packages/init/src/types.ts index a88735537..b750bd76a 100644 --- a/packages/init/src/types.ts +++ b/packages/init/src/types.ts @@ -11,13 +11,13 @@ import type { RequiredNotNull } from "./utils.ts"; /** Supported package manager identifiers: `"deno"`, `"pnpm"`, `"bun"`, `"yarn"`, `"npm"`. */ export type PackageManager = typeof PACKAGE_MANAGER[number]; -/** Supported web framework identifiers: `"hono"`, `"nitro"`, `"next"`, `"elysia"`, `"astro"`, `"express"`, `"sveltekit"`. */ +/** Supported web framework identifiers: `"bare-bones"`, `"hono"`, `"nitro"`, `"next"`, `"elysia"`, `"astro"`, `"express"`, `"nuxt"`, `"solidstart"`, `"sveltekit"`. */ export type WebFramework = typeof WEB_FRAMEWORK[number]; -/** Supported message queue identifiers: `"denokv"`, `"redis"`, `"postgres"`, `"amqp"`. */ +/** Supported message queue identifiers: `"in-process"`, `"redis"`, `"postgres"`, `"mysql"`, `"amqp"`, `"denokv"`. */ export type MessageQueue = typeof MESSAGE_QUEUE[number]; -/** Supported key-value store identifiers: `"denokv"`, `"redis"`, `"postgres"`. */ +/** Supported key-value store identifiers: `"in-memory"`, `"redis"`, `"postgres"`, `"mysql"`, `"denokv"`. */ export type KvStore = typeof KV_STORE[number]; /** A mapping from each {@link MessageQueue} identifier to its description. */ From 694408021cecd5d504317804e17211b8e7fed325 Mon Sep 17 00:00:00 2001 From: Palcimer Date: Fri, 31 Jul 2026 22:12:45 +0900 Subject: [PATCH 5/6] Wrap SvelteKit dev tasks with dotenvx Vite does not inject `.env` variables into `process.env`, so non-Deno SvelteKit projects failed during `mise test:init` runs that need KV/MQ connection settings (e.g. with `mysql`). Add `@dotenvx/dotenvx` as a dev dependency and wrap the `dev`/`build`/`preview` tasks with `dotenvx run --` for every non-Deno package manager. https://github.com/fedify-dev/fedify/issues/892 Assisted-by: Claude Code:claude-sonnet-5 --- packages/init/src/webframeworks/sveltekit.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/init/src/webframeworks/sveltekit.ts b/packages/init/src/webframeworks/sveltekit.ts index dc88d52e6..5ea808cf2 100644 --- a/packages/init/src/webframeworks/sveltekit.ts +++ b/packages/init/src/webframeworks/sveltekit.ts @@ -3,7 +3,7 @@ import deps from "../json/deps.json" with { type: "json" }; import { PACKAGE_VERSION, readTemplate } from "../lib.ts"; import type { PackageManager, WebFrameworkDescription } from "../types.ts"; import { defaultDenoDependencies, defaultDevDependencies } from "./const.ts"; -import { getInstruction, getNodeBunDevToolTasks } from "./utils.ts"; +import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.ts"; const sveltekitDescription: WebFrameworkDescription = { label: "SvelteKit", @@ -19,6 +19,9 @@ const sveltekitDescription: WebFrameworkDescription = { ...defaultDevDependencies, "typescript": deps["npm:typescript"], "@types/node": deps["npm:@types/node@25"], + ...(pmToRt(pm) === "deno" + ? {} + : { "@dotenvx/dotenvx": deps["npm:@dotenvx/dotenvx"] }), }, federationFile: "src/lib/federation.ts", loggingFile: "src/lib/logging.ts", @@ -26,7 +29,7 @@ const sveltekitDescription: WebFrameworkDescription = { files: { "src/hooks.server.ts": await readTemplate("sveltekit/hooks.server.ts"), }, - tasks: getNodeBunDevToolTasks(pm), + tasks: pmToRt(pm) === "deno" ? {} : { ...TASKS }, instruction: getInstruction(pm, 5173), }), }; @@ -61,3 +64,10 @@ const getSvelteKitInitCommand = (pm: PackageManager): string[] => : pm === "npm" ? ["npx", "sv", "create"] : [pm, "dlx", "sv", "create"]; + +const TASKS = { + "dev": "dotenvx run -- vite dev", + "build": "dotenvx run -- vite build", + "preview": "dotenvx run -- vite preview", + ...nodeBunDevToolTasks, +}; From 4f016f69b4ccb23e72d5381ff5936dfb124306df Mon Sep 17 00:00:00 2001 From: Palcimer Date: Fri, 31 Jul 2026 22:17:48 +0900 Subject: [PATCH 6/6] Update @fedify/init dependencies https://github.com/fedify-dev/fedify/issues/892 --- packages/init/src/json/deps.json | 30 +++++++++++++++--------------- packages/init/src/json/kv.json | 2 +- packages/init/src/json/mq.json | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/init/src/json/deps.json b/packages/init/src/json/deps.json index 24c4130c8..64ec5aefa 100644 --- a/packages/init/src/json/deps.json +++ b/packages/init/src/json/deps.json @@ -1,15 +1,15 @@ { "@hongminhee/x-forwarded-fetch": "^0.2.0", - "@hono/hono": "^4.12.27", - "@logtape/logtape": "^2.2.1", + "@hono/hono": "^4.12.33", + "@logtape/logtape": "^2.3.0", "@std/dotenv": "^0.225.7", - "npm:@astrojs/node": "^11.0.2", + "npm:@astrojs/node": "^11.0.3", "npm:@deno/astro-adapter": "^0.6.0", "npm:@dotenvx/dotenvx": "^1.75.1", "npm:@elysiajs/node": "^1.4.5", "npm:@hono/node-server": "^1.19.12", - "npm:@nuxt/kit": "^4.4.8", - "npm:@sinclair/typebox": "^0.34.49", + "npm:@nuxt/kit": "^4.5.1", + "npm:@sinclair/typebox": "^0.34.52", "npm:@solidjs/router": "^0.16.1", "npm:@solidjs/start": "^1.3.2", "npm:@types/bun": "^1.3.14", @@ -17,21 +17,21 @@ "npm:@types/node@20": "^20.11.2", "npm:@types/node@22": "^22.17.0", "npm:@types/node@25": "^25.5.0", - "npm:astro": "^7.0.7", - "npm:create-astro": "^5.2.2", + "npm:astro": "^7.1.6", + "npm:create-astro": "^5.2.3", "npm:elysia": "^1.4.29", "npm:express": "^5.2.1", "npm:h3": "^1.15.0", - "npm:hono": "^4.12.27", - "npm:nuxi": "^3.36.0", - "npm:nuxt": "^4.4.8", + "npm:hono": "^4.12.33", + "npm:nuxi": "^3.37.0", + "npm:nuxt": "^4.5.1", "npm:openapi-types": "^12.1.3", - "npm:oxfmt": "^0.56.0", - "npm:oxlint": "^1.71.0", - "npm:prettier": "^3.8.4", + "npm:oxfmt": "^0.61.0", + "npm:oxlint": "^1.76.0", + "npm:prettier": "^3.9.6", "npm:prettier-plugin-astro": "^0.14.1", - "npm:solid-js": "^1.9.13", - "npm:tsx": "^4.22.4", + "npm:solid-js": "^1.9.14", + "npm:tsx": "^4.23.1", "npm:typescript": "^5.9.3", "npm:vinxi": "^0.5.11", "npm:x-forwarded-fetch": "^0.2.0" diff --git a/packages/init/src/json/kv.json b/packages/init/src/json/kv.json index 1e574d818..28790f9ae 100644 --- a/packages/init/src/json/kv.json +++ b/packages/init/src/json/kv.json @@ -75,7 +75,7 @@ "pnpm" ], "dependencies": { - "npm:mysql2": "^3.22.5" + "npm:mysql2": "^3.23.2" }, "imports": { "@fedify/mysql": { diff --git a/packages/init/src/json/mq.json b/packages/init/src/json/mq.json index 98c65e658..5ef47aa3f 100644 --- a/packages/init/src/json/mq.json +++ b/packages/init/src/json/mq.json @@ -75,7 +75,7 @@ "pnpm" ], "dependencies": { - "npm:mysql2": "^3.22.5" + "npm:mysql2": "^3.23.2" }, "imports": { "@fedify/mysql": {