# spring-boot-vuejs: an example of wiring a Vue frontend to Spring Boot

> A Java and JavaScript sample project that serves a Vue single page app from a Spring Boot jar, packaged for Docker and Heroku, and used as a teaching example.

**jonashackt/spring-boot-vuejs** — Example project showing how to build a Spring Boot App providing a GUI with Vue.js

- Repository: https://github.com/jonashackt/spring-boot-vuejs
- Website: https://spring-boot-vuejs.herokuapp.com
- Stars: 2,121 · Forks: 666
- Language: Java
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/jonashackt-spring-boot-vuejs

## A sample project with an audience beyond GitHub

The repository describes itself as an example project showing how to build a Spring Boot app providing a GUI with Vue.js. That framing matters, because the README spends a good part of its length on why the author chose Vue, and on links to a JavaMagazin article, an entwickler.press eBook, a codecentric blog post and the Softwerker newsletter.

In other words, this is a teaching artefact with a publication history. The author, Jonas Hecht, works mostly on Spring Boot, microservices and Docker, and the README is candid about being out of his depth on the frontend. The section on searching for a new web frontend framework after two years of absence is written from that position, weighing Angular, React and Vue for someone whose frontend work is intermittent.

The scale suggests the example has been genuinely useful: 2,122 stars and 667 forks. That fork count is high relative to the star count, which is what you would expect from a repository people clone to adapt rather than merely read. It is MIT licensed, Java is the primary language, and the last push was on 2026-09-20.

## One Maven build produces both halves of the application

The repository tree is split into `backend/` and `frontend/` directories alongside a root `pom.xml`, plus the standard wrappers `mvnw` and `mvnw.cmd`. The version badges are unusually revealing: the Java badge is scraped from the root `pom.xml` parent version, while the Node badge is scraped from `frontend/pom.xml` and queries the `nodeVersion` of the build plugins. That tells you the frontend is built by Maven, not by a separate npm pipeline.

This is the core integration decision. The Vue project lives in `frontend/` and is compiled by a Node executing plugin inside the Maven lifecycle, which means `./mvnw package` produces a single Spring Boot jar with the compiled frontend inside it. The alternative would be a separate frontend build artifact and a static file server, which is more moving parts at deploy time and a more complex story in production.

There is also a `Procfile`, `system.properties` and `app.json` in the tree, which are the files Heroku expects. A live deployment is linked from the README, and a Docker Hub image is published as well. Between them, the packaging story is complete for both of the two platforms most people would reach for first.

## The Dockerfile is a two-stage build, and readable enough to learn from

The Dockerfile is short enough to read in full, which is a virtue in an example project. The first stage uses `maven:3-jdk-11`, copies the whole project in, and runs `mvn clean install`. The second stage is `openjdk:17.0.2-jdk`, and the comment above the copy says it is using the build artifact and removing the build container:

```dockerfile
FROM maven:3-jdk-11

ADD . /springbootvuejs
WORKDIR /springbootvuejs

RUN mvn clean install

FROM openjdk:17.0.2-jdk
```

Then the application jar is copied out of stage zero and started through an entrypoint that interpolates `JAVA_OPTS`:

```dockerfile
COPY --from=0 "/springbootvuejs/backend/target/backend-0.0.1-SNAPSHOT.jar" app.jar

ENV JAVA_OPTS=""

ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
```

The `-Djava.security.egd` flag is the container-era answer to slow entropy startup, and it is a small detail that tends to be absent from tutorials written before Docker was routine. Note the version mismatch between stages: the build uses JDK 11 and the runtime uses JDK 17, so the artifact is built against an older toolchain than it runs on.

## The documented upgrade path tells you which Vue generation this is

The README has an upgrade procedure section, and it is the most dated part of the document. It tells you to get the newest Node and npm, install the latest `@vue/cli` globally, and then run `vue upgrade`:

```shell
brew upgrade node
npm install -g npm@latest
```

```shell
npm install -g @vue/cli
```

```shell
vue upgrade
```

The `vue upgrade` command comes from vue-cli, and it links to the vue-cli migration guide for upgrading plugins. The repository topics confirm the vintage, listing `vue-cli`, `vue-cli-3` and `vue-cli-plugin` alongside `vuejs2`.

This is worth stating plainly rather than glossing over. Vue has moved on from the vue-cli toolchain, and a repository documenting `vue upgrade` as the way forward is describing an earlier generation of Vue tooling. Anyone picking this up in 2026 for a new project should use current official tooling. Anyone reading it to understand how the two halves were wired together at the time will find that still accurate.

## Branches exist for older toolchains, which is the honest archive

The README opens with a note aimed at readers of the German-language publications it appeared in, telling them to switch to the `vue-cli-v2-webpack-v3` branch instead. That branch name is itself a compact history of the frontend toolchain, and its existence tells you the author has kept older configurations working rather than letting them rot on the default branch.

That is the right pattern for an example project that has been cited in print, and it also means you should check which branch you are on before reading any instruction. The default branch documents the vue-cli generation, and older ones document the vue-cli 2 and webpack 3 generation.

The remaining badges describe the toolchain in detail: Bootstrap, TypeScript, webpack, axios, Jest and Nightwatch for browser tests, all version-scraped from `frontend/package.json` and the lock file. Having unit tests with Jest and end-to-end tests with Nightwatch in an example is a reasonable default for anyone copying the structure, even though it does double the tooling burden.

## Conclusion

Read spring-boot-vuejs as a worked example rather than a starting point. The valuable part is the shape of the integration, a Maven-built Spring Boot jar serving a compiled Vue bundle, with the frontend built through a Node plugin inside the Maven lifecycle so one artifact contains both halves. What it cannot tell you is whether any given version pairing is still current advice, since the Vue toolchain discussed in the README is the vue-cli generation that Vue has since moved past, and the repository points readers with newer setups at an older branch. If you want to see how the two halves are wired into one deployable, read the Dockerfile and the frontend build section. If you want to build a new Vue and Spring Boot application today, use the current official tooling instead.

## FAQ

### Is Spring Boot still relevant in 2026?

This repository is not in a position to answer that, since it is an example project rather than a framework. What it can show is one concrete integration: a Maven-built Spring Boot jar that serves a compiled Vue frontend from inside the same artifact, with Docker and Heroku packaging. For the framework question itself, the Spring project itself would be the place to look.

### How is the Vue frontend built and served?

The Vue project lives in `frontend/` and is compiled by a Node plugin inside the Maven lifecycle, so a single Maven package produces a Spring Boot jar containing the compiled frontend. The Dockerfile then copies that jar into a second stage and starts it with an entrypoint that honours `JAVA_OPTS`.

### Which Vue version does this example target?

The default branch targets the vue-cli generation, with topics listing `vue-cli`, `vue-cli-3` and `vuejs2`, and an upgrade section that documents `vue upgrade`. Older configurations live on a separate `vue-cli-v2-webpack-v3` branch, so check which branch you are on before following any instruction in the README.

### Does the example include tests?

The version badges show Jest for unit tests and Nightwatch for browser tests, both in the frontend dependencies. The repository also carries codecov, which indicates test coverage is tracked rather than merely present.

## Sources

- [Issues](https://github.com/jonashackt/spring-boot-vuejs/issues)
- [jonashackt/spring-boot-vuejs on GitHub](https://github.com/jonashackt/spring-boot-vuejs)
- [License: MIT](https://github.com/jonashackt/spring-boot-vuejs/blob/master/LICENSE)
- [Project website](https://spring-boot-vuejs.herokuapp.com)
- [README](https://github.com/jonashackt/spring-boot-vuejs/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jonashackt-spring-boot-vuejs
