Description of the bug
When vaadin.frontend.hotdeploy=true is enabled in a Gradle-based Spring Boot application, Vite first applies the frontend updates successfully on the client. Immediately afterward, a Gradle build is triggered, which runs the vaadinPrepareFrontend task. After that, the Vite dev server restart fails.
It occurs both with and without Spring Boot DevTools.
Relevant Log:
...
----------------- Frontend compiled successfully. -----------------
2026-04-11T13:08:10.237+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker :
2026-04-11T13:08:10.237+02:00 INFO 27058 --- [onPool-worker-1] c.v.b.devserver.AbstractDevServerRunner : Started Vite. Time: 806ms
2026-04-11T13:08:10.237+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : ➜ Local: http://127.0.0.1:52292/VAADIN/
2026-04-11T13:08:10.677+02:00 INFO 27058 --- [in-dev-server-2] c.v.b.d.DevModeHandlerManagerImpl : Application running at http://localhost:8080/
2026-04-11T13:08:11.069+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker :
2026-04-11T13:08:11.069+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [TypeScript] Found 0 errors. Watching for file changes.
2026-04-11T13:08:15.478+02:00 WARN 27058 --- [nio-8080-exec-2] c.vaadin.copilot.JavaSourcePathDetector : Multiple content roots ([.../base-starter-spring-gradle-25-1-1/src/main, .../base-starter-spring-gradle-25-1-1/build/vaadin-generated]) found for module base-starter-spring-gradle-25-1-1.main with Java source paths [.../base-starter-spring-gradle-25-1-1/src/main/java]
2026-04-11T13:08:28.801+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] build/vaadin-dev-server-settings.json changed, restarting server...
2026-04-11T13:08:28.802+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) page reload generated/vaadin-featureflags.js
2026-04-11T13:08:28.803+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) page reload generated/app-shell-imports.js
2026-04-11T13:08:28.803+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) page reload generated/vite-devmode.ts
2026-04-11T13:08:28.804+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) hmr update /generated/index.tsx
2026-04-11T13:08:28.804+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) hmr update /generated/vaadin-react.tsx
2026-04-11T13:08:28.804+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) hmr update /generated/flow/Flow.tsx
2026-04-11T13:08:28.831+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : vite v7.3.1 building client environment for development...
2026-04-11T13:08:28.849+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : transforming...
2026-04-11T13:08:28.931+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : ✓ 79 modules transformed.
2026-04-11T13:08:28.948+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : rendering chunks...
2026-04-11T13:08:28.954+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : ✓ built in 123ms
2026-04-11T13:08:28.964+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] server restarted.
2026-04-11T13:08:28.969+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) Pre-transform error: Failed to load url /generated/vite-devmode.ts (resolved id: /generated/vite-devmode.ts). Does the file exist?
2026-04-11T13:08:28.973+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] (client) Pre-transform error: Failed to resolve import "./index" from "src/main/frontend/generated/vaadin.ts". Does the file exist?
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : Plugin: vite:import-analysis
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : File: .../base-starter-spring-gradle-25-1-1/src/main/frontend/generated/vaadin.ts:51:7
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 43 | import "@vaadin/icons/vaadin-iconset.js";
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 44 | import "@vaadin/icon/vaadin-icon.js";
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 45 | import "./index";
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : | ^
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 46 | import "./vaadin-react.js";
2026-04-11T13:08:28.974+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 47 | import "Frontend/generated/jar-resources/vaadin-dev-tools/vaadin-dev-tools.js";
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : [vite] Internal server error: Failed to resolve import "./index" from "src/main/frontend/generated/vaadin.ts". Does the file exist?
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : Plugin: vite:import-analysis
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : File: .../base-starter-spring-gradle-25-1-1/src/main/frontend/generated/vaadin.ts:51:7
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 43 | import "@vaadin/icons/vaadin-iconset.js";
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 44 | import "@vaadin/icon/vaadin-icon.js";
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 45 | import "./index";
2026-04-11T13:08:29.130+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : | ^
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 46 | import "./vaadin-react.js";
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : 47 | import "Frontend/generated/jar-resources/vaadin-dev-tools/vaadin-dev-tools.js";
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at TransformPluginContext._formatLog (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:28999:43)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at TransformPluginContext.error (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:28996:14)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at normalizeUrl (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:27119:18)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:27177:32
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async Promise.all (index 30)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async TransformPluginContext.transform (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:27145:4)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async EnvironmentPluginContainer.transform (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:28797:14)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async loadAndTransform (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:22670:26)
2026-04-11T13:08:29.131+02:00 INFO 27058 --- [v-server-output] c.v.b.devserver.DevServerOutputTracker : at async viteTransformMiddleware (file://.../base-starter-spring-gradle-25-1-1/node_modules/vite/dist/node/chunks/config.js:24542:20)
...
Additionally, although it may be unrelated, the file vaadin-dev-server-settings.json changes, as shown in the logs, when vaadinPrepareFrontend is invoked after the CSS modification. The path's with .../build/classes/... changes to .../build/resources/main/...
Startup:
{
"frontendFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend",
"themeFolder": "themes",
"themeResourceFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources",
"staticOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/webapp/VAADIN/static",
"generatedFolder": "generated",
"statsOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/config",
"frontendBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/webapp",
"devBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/webapp",
"devBundleStatsOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/config",
"i18nOutput": "build/classes/vaadin-i18n",
"jarResourcesFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources",
"javaResourceFolder": ".../base-starter-spring-gradle-25-1-1/src/main/resources",
"themeName": "",
"clientServiceWorkerSource": ".../base-starter-spring-gradle-25-1-1/build/sw.ts",
"pwaEnabled": true,
"offlineEnabled": true,
"offlinePath": "'.'"
}
After change:
{
"frontendFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend",
"themeFolder": "themes",
"themeResourceFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources",
"staticOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/webapp/VAADIN/static",
"generatedFolder": "generated",
"statsOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/config",
"frontendBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/webapp",
"devBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/webapp",
"devBundleStatsOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/config",
"i18nOutput": "build/classes/vaadin-i18n",
"jarResourcesFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources",
"javaResourceFolder": ".../base-starter-spring-gradle-25-1-1/src/main/resources",
"themeName": "",
"clientServiceWorkerSource": ".../base-starter-spring-gradle-25-1-1/build/sw.ts",
"pwaEnabled": true,
"offlineEnabled": true,
"offlinePath": "'.'"
}
Expected behavior
Hot deployment of frontend files should work without causing the Vite dev server to fail.
Minimal reproducible example
- Clone base-starter-spring-gradle
- Add
vaadin.frontend.hotdeploy=true to applications.properties
- Start application with bootRun
- Open page in browser
- Change something in
styles.css under src/main/resources/META-INF/resources
- Select browser
Versions
- Vaadin / Flow version: 25.1.1
- Java version: 21 (Temurin)
- OS version: macOS 26.3.1
- IDE (if applicable): IntelliJ 2026.1
Description of the bug
When
vaadin.frontend.hotdeploy=trueis enabled in a Gradle-based Spring Boot application, Vite first applies the frontend updates successfully on the client. Immediately afterward, a Gradle build is triggered, which runs the vaadinPrepareFrontend task. After that, the Vite dev server restart fails.It occurs both with and without Spring Boot DevTools.
Relevant Log:
Additionally, although it may be unrelated, the file vaadin-dev-server-settings.json changes, as shown in the logs, when vaadinPrepareFrontend is invoked after the CSS modification. The path's with
.../build/classes/...changes to.../build/resources/main/...Startup:
{ "frontendFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend", "themeFolder": "themes", "themeResourceFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources", "staticOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/webapp/VAADIN/static", "generatedFolder": "generated", "statsOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/config", "frontendBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/classes/META-INF/VAADIN/webapp", "devBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/webapp", "devBundleStatsOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/config", "i18nOutput": "build/classes/vaadin-i18n", "jarResourcesFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources", "javaResourceFolder": ".../base-starter-spring-gradle-25-1-1/src/main/resources", "themeName": "", "clientServiceWorkerSource": ".../base-starter-spring-gradle-25-1-1/build/sw.ts", "pwaEnabled": true, "offlineEnabled": true, "offlinePath": "'.'" }After change:
{ "frontendFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend", "themeFolder": "themes", "themeResourceFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources", "staticOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/webapp/VAADIN/static", "generatedFolder": "generated", "statsOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/config", "frontendBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/resources/main/META-INF/VAADIN/webapp", "devBundleOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/webapp", "devBundleStatsOutput": ".../base-starter-spring-gradle-25-1-1/build/dev-bundle/config", "i18nOutput": "build/classes/vaadin-i18n", "jarResourcesFolder": ".../base-starter-spring-gradle-25-1-1/./src/main/frontend/generated/jar-resources", "javaResourceFolder": ".../base-starter-spring-gradle-25-1-1/src/main/resources", "themeName": "", "clientServiceWorkerSource": ".../base-starter-spring-gradle-25-1-1/build/sw.ts", "pwaEnabled": true, "offlineEnabled": true, "offlinePath": "'.'" }Expected behavior
Hot deployment of frontend files should work without causing the Vite dev server to fail.
Minimal reproducible example
vaadin.frontend.hotdeploy=truetoapplications.propertiesstyles.cssundersrc/main/resources/META-INF/resourcesVersions