Full-Stack E-Commerce App - Part 1: Project setup
Hey! Welcome to Part 1 of this series, where we build a complete, production-ready e-commerce app called ShopFlow — from an empty folder all the way to a live site on AWS. By the end of this series, ShopFlow will have: User authentication with JWT tokens A product catalogue with search powered by Elasticsearch A shopping cart (stored in Redis) and a full order system AI features — smart search, a chatbot, and product descriptions generated by AI Real payments via Stripe and PayPal Event-driven order processing with Apache Kafka Deployed on AWS with Kubernetes and a CI/CD pipeline That sounds like a lot — and it is! But we are going to build it one piece at a time . Each part of this series focuses on one thing, explains why we are doing it, and by the end, you have working code. In this fi
Hey! Welcome to Part 1 of this series, where we build a complete, production-ready e-commerce app called ShopFlow — from an empty folder all the way to a live site on AWS.
By the end of this series, ShopFlow will have:
-
User authentication with JWT tokens
-
A product catalogue with search powered by Elasticsearch
-
A shopping cart (stored in Redis) and a full order system
-
AI features — smart search, a chatbot, and product descriptions generated by AI
-
Real payments via Stripe and PayPal
-
Event-driven order processing with Apache Kafka
-
Deployed on AWS with Kubernetes and a CI/CD pipeline
That sounds like a lot — and it is! But we are going to build it one piece at a time. Each part of this series focuses on one thing, explains why we are doing it, and by the end, you have working code.
In this first part, we just focus on getting everything set up. By the end of this post, your backend and frontend will be running, talking to each other, and you'll understand what every piece does.
This series is aimed at developers who know some coding but maybe haven't built a full-stack app before, or want to see how all these technologies fit together in a real project. If you've followed any beginner tutorials but felt lost when it came to "real-world" apps, this series is for you.
Step 1 — Install the tools
Let's get your machine ready. We need four things: Java 21, Node.js 20, Docker Desktop, and an IDE.
Install Java 25
The best way to install Java is through SDKMAN — a tool that lets you easily switch between Java versions.
On macOS or Linux
Open your terminal and run this:
# Install SDKMAN curl -s "https://get.sdkman.io" | bash# Install SDKMAN curl -s "https://get.sdkman.io" | bashRestart your terminal, then install Java 25
sdk install java 25.0.2-tem
Check it worked
java -version
You should see: openjdk version "25.0.2"`
Enter fullscreen mode
Exit fullscreen mode
On Windows
Go to https://adoptium.net and download the "Temurin 25 LTS" Windows installer. Run it, and make sure you tick the option to set JAVA_HOME during setup.
After installing, open Command Prompt and check:
java -version
openjdk version "25.0.2" ...`
Enter fullscreen mode
Exit fullscreen mode
Install Node.js 22
We use Node.js to run our React frontend. The cleanest way to install it is through NVM (Node Version Manager) — it lets you easily switch between Node versions on the same machine.
On macOS or Linux
# Install NVM curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash# Install NVM curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bashRestart your terminal, then:
nvm install 22 nvm use 22
Check
node -v # v22.x.x npm -v # 10.x.x`
Enter fullscreen mode
Exit fullscreen mode
On Windows
Download nvm-windows from https://github.com/coreybutler/nvm-windows/releases (get nvm-setup.exe). Install it, then open a new terminal:
Install Docker Desktop
Go to https://docker.com/products/docker-desktop and download Docker Desktop for your OS. Install it and start it up. You'll know it's running when you see the whale icon in your menu bar or taskbar.
Check it's working:
docker -v
Docker version 29.x.x
docker compose version
Docker Compose version v2.x.x`
Enter fullscreen mode
Exit fullscreen mode
Install your IDE
For the backend (Java / Spring Boot): Download IntelliJ IDEA Community Edition for free from https://jetbrains.com/idea
For the frontend (React): Download VS Code for free from https://code.visualstudio.com
Once VS Code is open, install these extensions — they make working with React much nicer:
-
ES7+ React/Redux/React-Native snippets
-
Prettier — Code formatter
-
Tailwind CSS IntelliSense
-
Thunder Client (a Postman alternative built into VS Code — great for testing APIs)
Step 2 — Run MySQL in Docker
Create a new folder anywhere on your computer — call it shopflow. Inside it, create a file called docker-compose.yml and paste this in:
version: "3.8"
services: mysql: image: mysql:8.0 container_name: shopflow-mysql environment: MYSQL_ROOT_PASSWORD: shopflow123 MYSQL_DATABASE: shopflow_db MYSQL_USER: shopflow_user MYSQL_PASSWORD: shopflow123 ports:
- "3306:3306" volumes:
- mysql_data:/var/lib/mysql restart: unless-stopped
volumes: mysql_data:`
Enter fullscreen mode
Exit fullscreen mode
Now open a terminal in that folder and run:
docker compose up -d
-d means "detached" — runs in the background
Check it is running:
docker ps
You should see shopflow-mysql in the list with status "Up"`
Enter fullscreen mode
Exit fullscreen mode
Let's quickly connect to MySQL to make sure it's working:
docker exec -it shopflow-mysql mysql -u shopflow_user -p
Type the password: shopflow123
Once connected:
SHOW DATABASES;
You should see shopflow_db in the list
EXIT;`
Enter fullscreen mode
Exit fullscreen mode
Step 3 — Create the Spring Boot backend
Now let's create the backend. We'll use Spring Initializr — a free tool at start.spring.io that generates a ready-to-run Spring Boot project for you.
Generate the project
Go to https://start.spring.io and fill in the settings like this:
-
Project: Maven
-
Language: Java
-
Spring Boot version: 3.3.x (pick the latest stable, not a SNAPSHOT)
-
Group: com.shopflow
-
Artifact: backend
-
Java version: 25
Then click "ADD DEPENDENCIES" and add these:
-
Spring Web
-
Spring Data JPA
-
MySQL Driver
-
Spring Security
-
Spring Boot DevTools
-
Lombok
-
Validation
Click GENERATE — it downloads a zip file. Extract it into your shopflow/backend folder.
Open it in IntelliJ
Open IntelliJ IDEA. Go to File → Open and navigate to your shopflow/backend folder. IntelliJ will detect it's a Maven project and start downloading dependencies automatically. This takes 1–2 minutes the first time.
Connect it to the database
Open the file src/main/resources/application.properties and replace everything in it with:
# App name spring.application.name=shopflow-backend# App name spring.application.name=shopflow-backendDatabase connection
spring.datasource.url=jdbc:mysql://localhost:3306/shopflow_db spring.datasource.username=shopflow_user spring.datasource.password=shopflow123 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
JPA settings
spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
Server port
server.port=8080`
Enter fullscreen mode
Exit fullscreen mode
Run the app
Find the file BackendApplication.java inside src/main/java/com/shopflow/backend/ and click the green ▶ Run button next to the class name.
Watch the console at the bottom. After a few seconds, you should see:
Tomcat started on port(s): 8080 (http) Started BackendApplication in 2.847 secondsTomcat started on port(s): 8080 (http) Started BackendApplication in 2.847 secondsEnter fullscreen mode
Exit fullscreen mode
Open your browser and go to http://localhost:8080. You'll see a login page — that's Spring Security's default. It means the app is running. We'll replace this with our own auth in Part 2.
Step 4 — Create the React frontend
Now let's set up the frontend. We'll use Vite (pronounced "veet") instead of the old Create React App. Vite starts up in under a second and is way faster during development.
Create the project
Open a new terminal, go to your shopflow folder, and run:
npm create vite@latest frontend -- --template react cd frontend npm installnpm create vite@latest frontend -- --template react cd frontend npm installEnter fullscreen mode
Exit fullscreen mode
Now let's add the libraries we'll use throughout this series:
# Tailwind CSS — for styling without writing tons of CSS npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p# Tailwind CSS — for styling without writing tons of CSS npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -pReact Router — for navigation between pages
npm install react-router-dom
Axios — for making API calls to our backend
npm install axios
React Query — for managing server data in React
npm install @tanstack/react-query`
Enter fullscreen mode
Exit fullscreen mode
Configure Tailwind
Open tailwind.config.js and update the content section:
export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], }export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], }Enter fullscreen mode
Exit fullscreen mode
Then open src/index.css and replace everything with just these three lines:
@tailwind base; @tailwind components; @tailwind utilities;@tailwind base; @tailwind components; @tailwind utilities;Enter fullscreen mode
Exit fullscreen mode
Start the React dev server
npm run dev
You will see:
VITE v5.x.x ready in 300ms
➜ Local: http://localhost:5173/`
Enter fullscreen mode
Exit fullscreen mode
Open http://localhost:5173 in your browser. You should see the Vite + React welcome page. That means your frontend is running.
Step 5 — Make the frontend talk to the backend
This is the moment things get real. We're going to make a simple API endpoint in Spring Boot and call it from React.
Create a health check endpoint
In IntelliJ, create a new file: src/main/java/com/shopflow/backend/controller/HealthController.java
package com.shopflow.backend.controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map;
@RestController @RequestMapping("/api") public class HealthController {
@GetMapping("/health") public Map health() { return Map.of( "status", "ok", "message", "ShopFlow backend is running!" ); } }`
Enter fullscreen mode
Exit fullscreen mode
Let's break down what this does:
-
@RestController — tells Spring this class handles HTTP requests and returns data (not HTML pages)
-
@RequestMapping("/api") — all endpoints in this class start with /api
-
@GetMapping("/health") — when someone calls GET /api/health, run this method
Restart Spring Boot, then open http://localhost:8080/api/health in your browser. You should see:
{ "status": "ok", "message": "ShopFlow backend is running!" }{ "status": "ok", "message": "ShopFlow backend is running!" }Enter fullscreen mode
Exit fullscreen mode
Fix CORS so React can call the backend
Right now, if React tries to call the backend, the browser will block it with a CORS error. CORS is a browser security rule that blocks requests from different origins. Our frontend is on port 5173, our backend is on port 8080 — different origins.
Create a new file: src/main/java/com/shopflow/backend/config/CorsConfig.java
package com.shopflow.backend.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;
@Configuration public class CorsConfig {
@Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("http://localhost:5173"); config.addAllowedMethod(""); config.addAllowedHeader(""); config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/api/", config); return new CorsFilter(source); } }`
Enter fullscreen mode
Exit fullscreen mode
Call the API from React
Open src/App.jsx and replace everything with:
import { useState, useEffect } from "react" import axios from "axios"import { useState, useEffect } from "react" import axios from "axios"function App() { const [status, setStatus] = useState("Checking...")
useEffect(() => { axios.get("http://localhost:8080/api/health") .then(response => setStatus(response.data.message)) .catch(() => setStatus("Backend is not running!")) }, [])
return (
ShopFlow Full-stack e-commerce app Backend status: {status}
) }
export default App`
Enter fullscreen mode
Exit fullscreen mode
Restart Spring Boot (to pick up the CORS config), then open http://localhost:5173. You should see the ShopFlow card with:
"ShopFlow backend is running!"
That's it — your frontend and backend are talking to each other.
Step 6 — Folder structure and Git
Before we go any further, let's organise the project and save our work in Git.
Backend folder structure
This is the structure we'll follow for the whole course. Create these empty folders inside your backend project now so they're ready:
backend/src/main/java/com/shopflow/backend/ ├── config/ ← Spring configuration (CORS, Security, etc.) ├── controller/ ← API endpoints ├── service/ ← Business logic ├── repository/ ← Database access ├── model/ ← Entity classes (map to database tables) │ └── dto/ ← Data Transfer Objects (request/response shapes) ├── security/ ← Auth and JWT ├── exception/ ← Error handling └── util/ ← Helper utilitiesbackend/src/main/java/com/shopflow/backend/ ├── config/ ← Spring configuration (CORS, Security, etc.) ├── controller/ ← API endpoints ├── service/ ← Business logic ├── repository/ ← Database access ├── model/ ← Entity classes (map to database tables) │ └── dto/ ← Data Transfer Objects (request/response shapes) ├── security/ ← Auth and JWT ├── exception/ ← Error handling └── util/ ← Helper utilitiesEnter fullscreen mode
Exit fullscreen mode
This follows a layered architecture pattern: the request comes in through the Controller, the Controller calls the Service, the Service calls the Repository, the Repository talks to the database. Each layer only talks to the one below it.
Frontend folder structure
frontend/src/ ├── api/ ← API call functions (axios) ├── components/ ← Reusable UI pieces (buttons, cards, etc.) ├── pages/ ← Full page components ├── context/ ← React Context (auth state, cart state) ├── hooks/ ← Custom React hooks └── utils/ ← Helper functionsfrontend/src/ ├── api/ ← API call functions (axios) ├── components/ ← Reusable UI pieces (buttons, cards, etc.) ├── pages/ ← Full page components ├── context/ ← React Context (auth state, cart state) ├── hooks/ ← Custom React hooks └── utils/ ← Helper functionsEnter fullscreen mode
Exit fullscreen mode
Set up Git
In your shopflow root folder (the one that contains both backend and frontend), run:
git init git add . git commit -m "feat: initial project setup"git init git add . git commit -m "feat: initial project setup"Enter fullscreen mode
Exit fullscreen mode
Create a .gitignore file in the root:
# Java / Maven target/ *.class *.jar# Java / Maven target/ *.class *.jarIntelliJ
.idea/ .iml
Node
node_modules/ dist/
Environment files — NEVER commit these
.env .env.local
OS
.DS_Store Thumbs.db`
Enter fullscreen mode
Exit fullscreen mode
What's next?
In Part 2 of this series, we build the authentication system. That means:
-
Designing the user and roles database tables
-
Building register and login endpoints
-
Generating JWT tokens so users stay logged in
-
Protecting routes so only logged-in users can access them
-
Building the React login page and keeping auth state globally
Authentication is the foundation of the whole app — every other feature depends on it. See you in Part 2.
Sign in to highlight and annotate this article

Conversation starters
Daily AI Digest
Get the top 5 AI stories delivered to your inbox every morning.
More about
modelreleaseversion
AP ontving zoveel geld dat zij ruim 60.000 euro moet terugbetalen - update
De Nederlandse Autoriteit Persoonsgegevens ontving fors meer geld dan begroot, waardoor zij ruim 60.000 euro moest terugbetalen aan het ministerie van Justitie en Veiligheid. Dat blijkt uit het jaarverslag. De toezichthouder ontving in 2025 opnieuw meer klachten en signalen over potentiële misstanden. Die wist de organisatie niet allemaal af te handelen.

Alibaba Releases OpenSandbox to Provide Software Developers with a Unified, Secure, and Scalable API for Autonomous AI Agent Execution - MarkTechPost
Alibaba Releases OpenSandbox to Provide Software Developers with a Unified, Secure, and Scalable API for Autonomous AI Agent Execution MarkTechPost

Software-update - EVCC 0.304.0
EVCC is opensource energiebeheersoftware dat lokaal je laadpaal, zonnepanelen en stroomverbruik aanstuurt zonder afhankelijk te zijn van cloudservices. Het ondersteunt een groot aantal laadpalen, voertuigen en energiemeters en kan laden optimaliseren op basis van bijvoorbeeld zonne-energie of dynamische tarieven. Installatie is mogelijk op een Raspberry Pi, Docker, Linux, macOS of Windows, hoewel die laatste niet echt wordt aanbevolen. De changelog voor deze uitgave kan hieronder worden gevonden. Breaking Changes
Knowledge Map
Connected Articles — Knowledge Graph
This article is connected to other articles through shared AI topics and tags.
More in Products

New Advances Bring the Era of Quantum Computers Closer Than Ever
Two research groups say they have significantly reduced the amount of qubits and time required to crack common online security technologies. The post New Advances Bring the Era of Quantum Computers Closer Than Ever first appeared on Quanta Magazine




Discussion
Sign in to join the discussion
No comments yet — be the first to share your thoughts!