A production-grade Discord alternative featuring real-time chat, voice channels with WebRTC, file uploads, custom emojis, and more. Built with modern web technologies and fully containerized with Docker.
- Instant messaging with Socket.IO WebSockets
- Edit and delete your own messages (inline editing)
- Image/file attachments with preview before sending
- Custom emoji system per server (
:emoji_name:syntax) - Typing indicators
- Message notifications with toggleable sounds
- WebRTC peer-to-peer voice communication
- Mute / Deafen / Disconnect controls
- Screen sharing with stream viewing
- Connection quality indicator (ping, packet loss)
- Join/leave/disconnect sound effects
- Users visible under voice channels in sidebar
- Create and manage multiple servers
- Server settings (name, description, icon upload)
- Create, edit, and delete text/voice channels
- Invite system with shareable codes
- Role-based membership
- Join servers by name β search and join public servers
- Profile settings with avatar upload
- Discord-style member profile popovers
- Online/offline status indicators
- Display name customization
- Audio: Microphone and headset selection, mic test with volume meter
- Keybinds: Configurable shortcuts for mute, deafen, disconnect
- Notifications: Toggle message notification sounds
- Dark theme inspired by Discord
- Responsive layout with proper scrolling
- Smooth animations and transitions
- Custom scrollbars
βββββββββββββββ ββββββββββββββββ ββββββββββββββ
β Frontend ββββββΆβ Backend ββββββΆβ PostgreSQL β
β React+Vite β β NestJS β β (Prisma) β
β Port 3000 β β Port 4000 β β Port 5432 β
βββββββββββββββ ββββββββ¬ββββββββ ββββββββββββββ
β
ββββββββ΄ββββββββ
β β
βββββββΌββββββ βββββββΌββββββ
β MinIO β β Coturn β
β S3 Storage β β TURN/STUN β
β Port 9000 β β Port 3478 β
βββββββββββββ βββββββββββββ
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS, Zustand |
| Backend | NestJS, TypeScript, Prisma ORM, Socket.IO |
| Database | PostgreSQL 15 |
| Storage | MinIO (S3-compatible) |
| Voice/Video | WebRTC + Coturn TURN/STUN server |
| Deployment | Docker Compose |
- Docker and Docker Compose
- Git
# Clone the repository
git clone https://github.com/Sliv3er/BattalaHub.git
cd BattalaHub
# Start all services
docker compose up -d
# Wait for services to be healthy, then open:
# Frontend: http://localhost:3000
# Backend API: http://localhost:4000/api/docs (Swagger)
# MinIO Console: http://localhost:9001| Service | Port |
|---|---|
| Frontend | 3000 |
| Backend API | 4000 |
| PostgreSQL | 5432 |
| MinIO API | 9000 |
| MinIO Console | 9001 |
| Coturn STUN/TURN | 3478 |
battala-hub/
βββ backend/ # NestJS API server
β βββ prisma/
β β βββ schema.prisma # Database schema (12+ models)
β βββ src/
β β βββ auth/ # JWT authentication
β β βββ channels/ # Channel CRUD
β β βββ database/ # Prisma service
β β βββ emojis/ # Custom emoji system
β β βββ messages/ # Message CRUD + reactions
β β βββ servers/ # Server management + invites
β β βββ storage/ # MinIO file uploads
β β βββ users/ # User profiles
β β βββ voice/ # Voice channel management
β β βββ websocket/ # Socket.IO gateways (chat + voice)
β β βββ main.ts # App bootstrap
β βββ Dockerfile
βββ frontend/ # React SPA
β βββ src/
β β βββ api/ # Axios client
β β βββ components/ # UI components
β β β βββ AppSettings.tsx
β β β βββ ChannelsSidebar.tsx
β β β βββ ChatArea.tsx
β β β βββ MembersList.tsx
β β β βββ ProfileSettings.tsx
β β β βββ ServerSettings.tsx
β β β βββ VoiceChannel.tsx
β β βββ pages/ # Route pages
β β βββ stores/ # Zustand state management
β β β βββ authStore.ts
β β β βββ settingsStore.ts
β β β βββ socketStore.ts
β β β βββ voiceStore.ts
β β βββ main.tsx
β βββ Dockerfile
βββ coturn/ # TURN server config
βββ docker-compose.yml # Full stack orchestration
βββ README.md
POST /api/auth/registerβ Register new userPOST /api/auth/loginβ LoginPOST /api/auth/logoutβ LogoutGET /api/auth/meβ Get current user
POST /api/serversβ Create serverGET /api/serversβ List user's serversGET /api/servers/:idβ Get server detailsPATCH /api/servers/:idβ Update serverDELETE /api/servers/:idβ Delete serverGET /api/servers/search?name=β Search servers by namePOST /api/servers/:id/joinβ Join serverPOST /api/servers/:id/invitesβ Create invitePOST /api/servers/join/:inviteCodeβ Join via invite
POST /api/channels/:serverIdβ Create channelGET /api/channels/server/:serverIdβ List channelsPATCH /api/channels/:idβ Update channelDELETE /api/channels/:idβ Delete channel
POST /api/messages/channel/:channelIdβ Send messageGET /api/messages/channel/:channelIdβ Get messagesPATCH /api/messages/:idβ Edit messageDELETE /api/messages/:idβ Delete messagePOST /api/messages/:id/reactionsβ Add reaction
GET /api/voice/ice-serversβ Get ICE serversPOST /api/voice/channels/:channelId/joinβ Join voiceDELETE /api/voice/leaveβ Leave voiceGET /api/voice/channels/:channelId/usersβ Get voice users
POST /api/emojis/:serverIdβ Upload custom emojiGET /api/emojis/:serverIdβ List server emojisDELETE /api/emojis/:idβ Delete emoji
POST /api/storage/uploadβ Upload file (max 10MB)
| Event | Direction | Description |
|---|---|---|
join_channel |
Client β Server | Join a text channel |
leave_channel |
Client β Server | Leave a text channel |
send_message |
Client β Server | Send a message |
edit_message |
Client β Server | Edit a message |
delete_message |
Client β Server | Delete a message |
add_reaction |
Client β Server | Add emoji reaction |
typing_start |
Client β Server | Start typing indicator |
new_message |
Server β Client | New message received |
message_updated |
Server β Client | Message was edited |
message_deleted |
Server β Client | Message was deleted |
user_typing |
Server β Client | User is typing |
| Event | Direction | Description |
|---|---|---|
join_voice |
Client β Server | Join voice channel |
leave_voice |
Client β Server | Leave voice channel |
webrtc_offer |
Bidirectional | WebRTC SDP offer |
webrtc_answer |
Bidirectional | WebRTC SDP answer |
webrtc_ice_candidate |
Bidirectional | ICE candidate exchange |
user_joined_voice |
Server β Client | User joined voice |
user_left_voice |
Server β Client | User left voice |
Key models: User, Server, ServerMember, Role, Channel (TEXT/VOICE), Message, Reaction, Attachment, Emoji, Invite, VoiceSession, TypingIndicator
See backend/prisma/schema.prisma for full schema.
All configured via docker-compose.yml. Key variables:
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Set in compose |
JWT_SECRET |
JWT signing key | Set in compose |
MINIO_ENDPOINT |
MinIO internal hostname | minio |
MINIO_PUBLIC_URL |
MinIO public URL for browser | http://localhost:9000 |
CORS_ORIGIN |
Allowed CORS origin | http://localhost:3000 |
TURN_SERVER_URL |
Coturn TURN server URL | turn:coturn:3478 |
MIT
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request