diff --git a/cli/test/dev_server.test.ts b/cli/test/dev_server.test.ts
index be243b645d..6c825a9bbd 100644
--- a/cli/test/dev_server.test.ts
+++ b/cli/test/dev_server.test.ts
@@ -404,6 +404,197 @@ export default function App() {
} finally {
clearTimeout(sseTimeout);
}
+
+ // Verify esbuild bundle is served and contains valid JS
+ const bundleRes = await fetch(`http://localhost:${port}/dist/bundle.js`);
+ expect(bundleRes.status).toEqual(200);
+ expect(bundleRes.headers.get("content-type")).toContain("application/javascript");
+ const bundleJs = await bundleRes.text();
+ expect(bundleJs.length).toBeGreaterThan(100);
+ // The bundle should contain the React app code
+ expect(bundleJs).toContain("Hello from test app");
+
+ // Verify source map is served
+ const mapRes = await fetch(`http://localhost:${port}/dist/bundle.js.map`);
+ expect(mapRes.status).toEqual(200);
+ expect(mapRes.headers.get("content-type")).toContain("application/json");
+ const sourceMap = await mapRes.json() as any;
+ expect(sourceMap.version).toEqual(3);
+ expect(sourceMap.sources).toBeArray();
+ } finally {
+ if (proc) {
+ proc.kill();
+ await proc.exited;
+ }
+ }
+ });
+ },
+ { timeout: 120000 },
+);
+
+// =============================================================================
+// TEST 3: `wmill app dev` with Svelte app — verifies esbuild + Svelte plugin
+// =============================================================================
+
+test(
+ "wmill app dev: Svelte app bundles correctly and serves valid JS",
+ async () => {
+ await withTestBackend(async (backend, tempDir) => {
+ await writeFile(
+ join(tempDir, "wmill.yaml"),
+ "defaultTs: bun\n",
+ "utf-8",
+ );
+
+ const appDir = join(tempDir, "f", "test", "svelteapp.raw_app");
+ await mkdir(appDir, { recursive: true });
+
+ await writeFile(
+ join(appDir, "raw_app.yaml"),
+ `custom_path: f/test/svelteapp\n`,
+ "utf-8",
+ );
+
+ await writeFile(
+ join(appDir, "package.json"),
+ JSON.stringify(
+ {
+ name: "test-svelte-app",
+ private: true,
+ dependencies: {
+ svelte: "^5.0.0",
+ },
+ },
+ null,
+ 2,
+ ),
+ "utf-8",
+ );
+
+ // Svelte apps use index.ts (not index.tsx)
+ await writeFile(
+ join(appDir, "index.ts"),
+ `import App from "./App.svelte";
+import { mount } from "svelte";
+
+const app = mount(App, { target: document.getElementById("root")! });
+export default app;
+`,
+ "utf-8",
+ );
+
+ await writeFile(
+ join(appDir, "App.svelte"),
+ `
+
+
Svelte Dev Test
+
+`,
+ "utf-8",
+ );
+
+ // npm install
+ const npmInstall = Bun.spawn(["npm", "install"], {
+ cwd: appDir,
+ stdout: "pipe",
+ stderr: "pipe",
+ });
+ await Promise.all([
+ new Response(npmInstall.stdout).text(),
+ new Response(npmInstall.stderr).text(),
+ ]);
+ expect(await npmInstall.exited).toEqual(0);
+
+ const port = await findFreePort();
+
+ const cliMainPath = getCLIMainPath();
+ const args = [
+ "run",
+ cliMainPath,
+ "--base-url",
+ backend.baseUrl,
+ "--workspace",
+ backend.workspace,
+ "--token",
+ backend.token!,
+ "--config-dir",
+ backend.testConfigDir,
+ "app",
+ "dev",
+ appDir,
+ "--no-open",
+ "--port",
+ String(port),
+ ];
+
+ let proc: Subprocess | null = null;
+
+ try {
+ proc = Bun.spawn(["bun", ...args], {
+ cwd: tempDir,
+ stdout: "pipe",
+ stderr: "pipe",
+ env: { ...process.env },
+ });
+
+ // Collect stderr for debugging on failure
+ const stderrReader = proc.stderr.getReader();
+ let stderrBuffer = "";
+ (async () => {
+ try {
+ while (true) {
+ const { done, value } = await stderrReader.read();
+ if (done) break;
+ stderrBuffer += new TextDecoder().decode(value);
+ }
+ } catch {
+ // Process may have exited
+ }
+ })();
+
+ // Wait for the bundle to be ready (poll /dist/bundle.js instead of just /)
+ await waitFor(
+ async () => {
+ try {
+ const res = await fetch(`http://localhost:${port}/dist/bundle.js`, {
+ signal: AbortSignal.timeout(1000),
+ });
+ if (res.ok) {
+ const text = await res.text();
+ // Only consider ready when bundle has real content (not empty/placeholder)
+ return text.length > 100;
+ }
+ await res.text();
+ } catch {
+ // Not ready yet
+ }
+ return false;
+ },
+ 60000,
+ "Svelte app dev server bundle to be ready",
+ );
+
+ // Verify HTML is served with correct structure
+ const htmlRes = await fetch(`http://localhost:${port}/`);
+ const htmlBody = await htmlRes.text();
+ expect(htmlBody).toContain("");
+ expect(htmlBody).toContain('');
+
+ // Verify the JS bundle contains compiled Svelte code
+ const bundleRes = await fetch(`http://localhost:${port}/dist/bundle.js`);
+ expect(bundleRes.status).toEqual(200);
+ const bundleJs = await bundleRes.text();
+ expect(bundleJs.length).toBeGreaterThan(100);
+ // The bundle should contain the Svelte component text
+ expect(bundleJs).toContain("Svelte Dev Test");
+
+ // Verify source map
+ const mapRes = await fetch(`http://localhost:${port}/dist/bundle.js.map`);
+ expect(mapRes.status).toEqual(200);
+ const sourceMap = await mapRes.json() as any;
+ expect(sourceMap.version).toEqual(3);
} finally {
if (proc) {
proc.kill();