Spring + React
Next.js is a common choice for apps that use React and render pages on the server. For task queues, scheduled jobs, and other background work, you may also need a backend framework. Go projects often use Fiber or Gin. For Java and Kotlin, Spring Boot is a popular choice, though comparing a framework with a language is not a direct comparison.
We can let Spring Boot handle the backend and use plain React for the frontend. To serve both from one server, build the React app and have Spring Boot serve the output as static files.
Spring Boot
Create a project with Spring Initializr and add the development tools dependency:
runtimeOnly("org.springframework.boot:spring-boot-devtools")In *Application.kt, the entry point for the Spring Boot app, add a view controller for the home page:
@SpringBootApplication
class Application : WebMvcConfigurer {
override fun addViewControllers(registry: ViewControllerRegistry) {
registry.addViewController("/").setViewName("index.html")
}
}Vite
Vite builds the frontend and can rebuild it when source files change.
Set its output directory to src/main/resources/static, where Spring Boot serves static files by default.
Add this to vite.config.ts:
export default defineConfig({
build: {
outDir: "../src/main/resources/static",
},
});Then run these commands:
$ pnpm init vite@latest
$ ... # follow the instructions
$ cd client
$ pnpm install
$ vite build --watch --emptyOutDirWatching static files for changes
Spring Boot does not watch static files for changes by default. The devtools dependency above supports restarting the server and reloading the page during development.
Add these settings to application.yaml so the server watches the frontend output:
spring:
devtools:
restart:
enabled: true
additional-paths: file:src/main/resources/static
web:
resources:
static-locations: file:src/main/resources/staticThe server will rebuild and restart when those files change.
A similar setup in Go
With fiber in Go, air can watch backend files and restart the server when they change.
Go builds are reasonably fast compared with Spring Boot, which makes it quicker to try changes. I also like having a single binary that serves both the frontend and backend.