Build and run a realtime chat application powered by a Spring Boot backend (WebSocket + STOMP + MongoDB) and a modern React + Vite + Tailwind frontend.
- Rooms: Create or join chat rooms by ID
- Realtime messaging: STOMP over SockJS with topic subscriptions
- Message history: Stored in MongoDB with simple pagination
- Clean UI: React + Tailwind with emoji support and toasts
- Backend: Spring Boot 3, WebSocket (STOMP), Spring Data MongoDB, Lombok
- Frontend: React 18, Vite, TailwindCSS,
@stomp/stompjs,sockjs-client, Axios - Database: MongoDB
- Java 21 (JDK 21)
- Maven 3.9+
- Node.js 18+
- MongoDB running locally on
mongodb://localhost:27017
git clone <your-repo-url>
cd chat-appcd chat-app
mvn spring-boot:run- Backend starts on
http://localhost:8080 - WebSocket endpoint is served at
http://localhost:8080/chat - MongoDB connection string is configured in
chat-app/src/main/resources/application.properties:spring.data.mongodb.uri=mongodb://localhost:27017/chatapp
cd ../frontend
npm install
npm run dev- Frontend runs at
http://localhost:5173 - API base URL is set in
frontend/src/config/AxiosHelper.js→http://localhost:8080
- Backend CORS and WebSocket allowed origin:
http://localhost:5173 - Update origins if you deploy the frontend to a different host.
Base URL: http://localhost:8080
| Method | Endpoint | Body | Description |
|---|---|---|---|
| POST | /api/v1/rooms |
text/plain | Create a room by ID |
| GET | /api/v1/rooms/{roomId} |
– | Join/fetch a room |
| GET | /api/v1/rooms/{roomId}/messages |
– | Get messages (paged) |
Query params for messages: size (default 20), page (default 0). Pagination is applied server-side using a simple slice of the list.
Create a room (text/plain body):
curl -X POST \
-H "Content-Type: text/plain" \
--data "my-room-123" \
http://localhost:8080/api/v1/roomsJoin a room:
curl http://localhost:8080/api/v1/rooms/my-room-123Fetch messages:
curl "http://localhost:8080/api/v1/rooms/my-room-123/messages?size=50&page=0"- SockJS endpoint:
http://localhost:8080/chat - STOMP app destination prefix:
/app - Topic prefix:
/topic
Subscribe to receive messages for a specific room:
/topic/room/{roomId}
Send to the mapped app destination:
/app/sendMessage/{roomId}
Payload (JSON), matches MessageRequest:
{
"sender": "alice",
"content": "Hello, world!",
"roomId": "my-room-123"
}import SockJS from 'sockjs-client';
import { Stomp } from '@stomp/stompjs';
const sock = new SockJS('http://localhost:8080/chat');
const client = Stomp.over(sock);
client.connect({}, () => {
const roomId = 'my-room-123';
client.subscribe(`/topic/room/${roomId}`, (frame) => {
console.log('New message:', JSON.parse(frame.body));
});
client.send(
`/app/sendMessage/${roomId}`,
{},
JSON.stringify({ sender: 'alice', content: 'Hi!', roomId })
);
});Note: The frontend hook also sends a presence heartbeat to /app/presence/{roomId}/heartbeat for liveness, which you can extend on the server side if desired.
chat-app/
├─ chat-app/ # Spring Boot backend
│ ├─ src/main/java/com/example
│ │ ├─ config/WebSocketConfig.java
│ │ ├─ controllers/ChatController.java
│ │ ├─ controllers/RoomController.java
│ │ ├─ entities/{Room, Message}.java
│ │ ├─ repositories/RoomRepository.java
│ │ └─ payload/MessageRequest.java
│ └─ src/main/resources/application.properties
└─ frontend/ # React + Vite frontend
├─ src/config/AxiosHelper.js
├─ src/services/RoomService.js
├─ src/components/*
└─ vite/tailwind configs
# from ./frontend
npm run dev # start dev server (http://localhost:5173)
npm run build # production build
npm run preview # preview production build
npm run lint # lint# from ./chat-app
mvn spring-boot:run # run locally
mvn -q -DskipTests package # build jar (skip tests)- WebSocket not connecting? Ensure backend is on port 8080 and frontend base URL is
http://localhost:8080. Check CORS/origin settings inWebSocketConfigand@CrossOriginannotations. - MongoDB errors? Make sure MongoDB is running locally on
mongodb://localhost:27017and thechatappdatabase is accessible. - Room creation fails with 400? The POST body must be
text/plainwith the room ID string only. - Not receiving messages? Verify you are subscribed to
/topic/room/{roomId}and sending to/app/sendMessage/{roomId}with a valid JSON body.
Add your preferred license here (e.g., MIT).
Built with ❤️ using Spring Boot, React, and MongoDB.