Run React and SpringBoot on the same port and Package them as a single artifact !!

It requires frontend-maven-plugin, maven-resources-plugin and thymleaf.

Arpan Banerjee
CodeX
6 min readApr 11, 2021

--

Photo by Artem Sapegin on Unsplash

Hey there! I am a full stack developer with 3+ years of experience based out of West Bengal, India. Today I will walk you through a setup trick to prepare your project structure for running react and spring boot app on the same port, and package them as a single artifact. You will see how easy this can make development when dealing with both of these game-changing technologies.

Here is the GitHub link to the demo that I am going to explain here.

Advantages of this setup

1. Combines the ease of development of both create-react-app and Spring Boot.

2. You can use the hot reload feature of create-react-app while developing the frontend, save the page after making changes and it will reflect immediately on the browser.

3. Using Spring Boot you can easily manage your development versions (using SNAPSHOTs) and release versions in production. You can detect build version and time at runtime in Spring Boot using Spring Actuator or Spring Admin, which can provide the build metadata functionality plus a lot more.

4. Package Frontend and Backend in a single war/jar file with optimized production build.

I learned this in one of my recent projects. It has several spring boot microservices with react frontend packaged and deployed as single artifacts of their own.

So, here is a quick guide how to run a react frontend and a spring boot backend on the same port and how to package them as a single jar file.

First, create a spring boot project with https://start.spring.io. Add the Web dependency. Set the groupidand artifactidto whatever you want. Generate the project and unzip it into your project directory.

Or, if you are using Spring Tools Suite you can simply click File->new->Spring Starter Project mention the required details to create a spring boot project.

Your initial pom.xml should look like this.

pom.xml

The project structure should look like this.

You can run the app now and see if it runs without any errors.
Though you won’t see anything if you hit http://localhost:8080/ .

http://localhost:8080/

Now, go to src/main/resources, create a static folder. Inside it create a test.html file with some text in it.

Now, if you restart the application and hit http://localhost:8080/test.html you will see it spins up your html page in port 8080. You can see the contents of your file in the browser.

http://localhost:8080/test.html

Serving the React App from Spring Boot on port 8080 and Packaging them together

We will exploit the above mentioned feature of Spring Boot to serve the single page of the react project. We will serve a html page from the `static` folder in the `target` directory, not in the source directory.

Now let’s create a react app, using create-react-app. Navigate to your folder till src/main in a terminal.

D:\Codes_projects\srpingboot_react_maven_plugin\Spring_React_maven-plugin\src\main and run npx create-react-app frontend.

This should create a react app inside src/main. Now if you look at your folder structure it should look like this.

You can run the react app, by doing cd frontendand then yarn start or npm start. It should spin up the react app on http://localhost:3000.

http://localhost:3000

You can create a production build of the frontend by running yarn build. Your folder structure after running the build command will look like this.

You need to copy this production build place it inside the `target/classes` directory of your project to enable Spring Boot to serve this `index.html` when you start your project

So, there are two steps-

1. create a production build of the frontend
2. copy the production build into ${target/classes/}

Of course you are not going to do that manually.
We we will use two `maven plugins` for that.

1. frontend-maven-plugin for step
2.
maven-resources-plugin for step 2.

Add the following to your pom.xml under the plugins section and update the propertiessection as shown.

Properties section of pom.xml
Plugins section of pom.xml

Now if you run mvn clean installfrom D:\Codes_projects\springboot_react_maven_plugin\Spring_React_maven-plugin maven will install npm, yarnand nodelocally and run npm buildin the frontend directory.

Console

The folder structure would look like this-

Now, add the second plugin to your pom.xml.

Plugins section of pom.xml

Add the following dependency in the dependencies section.

Dependencies section of pom.xml

Modify the spring-boot-maven-plugin to include a configuration section.

Plugins section of pom.xml

This will ensure that the frontend build files are copied after they have been generated by yarn build.
Now, run mvn clean installagain and inspect the target/classes/static directory from your file manager.

File Manager

It will have the frontend production build files in there.

Now you are ready to go! Run the project and go to http://localhost:8080/index.html VOILA!! You have run your React app via Spring Boot.

http://localhost:8080/index.html

Final Pom.xml

pom.xml

Taking a step further

You can add rest controllersand expose an endpoint to be the starting point of the application. Like an Index Controller, whenever the application loads, spring boot will spin up the index.htmlfile having the static contents from the optimized build of the frontend project from the `target directory`. So that you can simply visit http://localhost:8080and not hardcode the index.htmlfile name.

Let’s do that.
Add a controller, in the following folder structure.

IndexController.java

Run your application and hit http://localhost:8080/.
Did you see anything? No, right!

You have to add another dependency for this to work.

Dependencies section of pom.xml

Now, by default Thymleaf looks for our templates in src/main/resources/templates. We can put our templates there and organize them in sub-directories and have no issues.

So, let’s try that. Add a html file inside src/main/resources/templates named index.html and put some content in it.

Run the application and visit http://localhost:8080You will see the index.hymlfrom src/main/resources/templatesbeing served in port 8080.

http://localhost:8080

Now, to change this default behaviour and make Thymleaf serve static content from another location, you need to add an entry to the application.propertiesfile.

Here, I have hardcoded the path.

Finally, now if you `update` your project and start it. You can see the react app being served directly on port 8080.

http://localhost:8080

Conclusion

You have learned how to use spring boot to run a react app. You can run both your frontend and backend on the same port. I have explained what you need to do to get the setup done. You can now create a meaningful application, and see how easy and quick it is to develop with this setup. You can now run the frontend application using React-scripts by running cd frontedn; yarn start, and develop using the hot reload feature of create-react-app and have meaningful error messages, while being able to deploy the application to test and production environments as a single artifact.

Thanks for reading!

Please leave a comment if you find this helpful. Any feedback or suggestions are welcome.

--

--

Arpan Banerjee
CodeX

Software Engineer III @ Walmart | Java | JavaScript | Spring | React | Docker | Linkedin : https://www.linkedin.com/in/banerjee-arpan7/