A full-stack, real-time video calling and messaging platform built with the MERN stack and Stream API.
Streamify is a modern, responsive web application designed to connect users through seamless real-time video calls and text messaging. Whether you're looking to catch up with friends, collaborate with a team, or build out a scalable community, Streamify provides the infrastructure to do so effortlessly.
The platform is meticulously architected by decoupling the frontend and backend to ensure scalability and ease of maintenance. It features dynamic theming capabilities, instantaneous communication powered by WebRTC (via Stream), and a robust backend ensuring your data is secure.
- π Secure Authentication: JWT-based stateless authentication with robust password hashing (bcrypt).
- πΉ Real-Time Video & Chat: Integrated with the Stream.io SDK for enterprise-grade video calling and messaging.
- π€ Social Mechanics: Discover recommended users, send friend requests, and manage your network dynamically.
- π¨ Dynamic Theming: Globally manageable UI themes using DaisyUI and Zustand state management.
- β‘ Lightning Fast: Powered by Vite on the frontend for instant HMR and optimized production builds.
- π Efficient Data Fetching: Utilizes
@tanstack/react-queryto eliminate manual loading states and handle caching effectively.
The repository is structured as a monorepo containing both the frontend and backend codebases.
The frontend is built for speed, responsiveness, and excellent developer experience. It interacts seamlessly with our backend APIs as well as directly with Stream's WebSocket services for real-time capabilities.
- Core Framework: React (Bootstrapped with Vite)
- Routing: React Router v7 for declarative and nested navigation.
- State Management:
- Server State:
@tanstack/react-queryhandles caching, background updates, and eliminates boilerplate for loading/error states. - Client/Global State:
zustandis used for lightweight, globally accessible state management, primarily for dynamic theming.
- Server State:
- Styling: Tailwind CSS combined with DaisyUI components, offering a robust theming system (e.g.,
data-theme). - Real-time UI Components:
stream-chat-reactprovides pre-built, highly customizable chat UI interfaces (MessageList, Thread, Channel, etc.). - Notifications:
react-hot-toastfor elegant, non-intrusive toast alerts.
The backend serves as a secure RESTful API that handles user authentication, database management, and securely generating tokens required for the Stream SDK.
- Runtime & Framework: Node.js and Express.js
- Database: MongoDB hosted on Atlas, modeled and queried using
mongoose. - Authentication & Security:
bcryptjsfor secure password hashing (utilizing Mongoose pre-save hooks).jsonwebtoken(JWT) for stateless, secure HTTP-Only cookie-based sessions.cookie-parserandcorsfor handling cross-origin credentialed requests.
- Real-time Integration: The
stream-chatNode SDK is used server-side to sync user records (upserting users) and generate secure client access tokens. - Production Serving: In production, the Express server is configured to statically serve the compiled React application, allowing for a unified single-port deployment on platforms like Render.
streamify/
βββ backend/ # Express API Server
β βββ src/
β β βββ controllers/ # Route controllers (auth, chat, user activities)
β β βββ lib/ # Database & Stream API configurations
β β βββ middleware/ # JWT Authentication middleware (protectRoute)
β β βββ models/ # Mongoose schemas (User, FriendRequest)
β β βββ routes/ # Express API routes
β β βββ server.js # Backend entry point
β βββ package.json
βββ frontend/ # React Vite Client
β βββ public/
β βββ src/
β β βββ components/ # Reusable UI components (Navbar, Sidebar, PageLoader)
β β βββ constants/ # Application constants
β β βββ hooks/ # Custom React hooks (e.g., useAuthUser)
β β βββ lib/ # Axios configuration (axiosInstance)
β β βββ pages/ # Application routes (Home, Chat, Login, Notifications)
β β βββ store/ # Zustand global state (useThemeStore)
β β βββ App.jsx # Main React component & Routing Hub
β β βββ main.jsx # Frontend entry point & Context Providers
β βββ package.json
βββ package.json # Root project dependencies & deployment scripts
Follow these instructions to set up the project locally.
- Node.js installed on your local machine.
- A MongoDB Atlas account and database connection string. (Ensure Network Access is set to
0.0.0.0/0during development). - A Stream.io account. Create an organization and an app to grab your API keys.
-
Clone the repository
git clone https://github.com/yourusername/streamify.git cd streamify -
Install Dependencies You can install dependencies for both the frontend and backend using the root script:
npm install --prefix backend npm install --prefix frontend
-
Setup Environment Variables
Create a
.envfile in thebackend/directory:PORT=5001 MONGODB_URI=your_mongodb_connection_string JWT_SECRET=your_secure_random_string # Tip: use `openssl rand -base64 32` STREAM_API_KEY=your_stream_api_key STREAM_API_SECRET=your_stream_api_secret NODE_ENV=development
Create a
.envfile in thefrontend/directory:VITE_STREAM_API_KEY=your_stream_api_key
To run the application in a development environment, you need two terminals.
Terminal 1 (Backend):
cd backend
npm run dev(Runs on http://localhost:5001 with nodemon)
Terminal 2 (Frontend):
cd frontend
npm run dev(Runs on Vite's default dev port, proxying requests to the backend)
Streamify can be deployed using two different approaches: Decoupled Deployment (Highly Recommended) or Unified Monolithic Deployment.
Deploying the frontend statically to Vercel and backend to Render provides superior loading performance and scale.
- Deploy your backend code from the
/backendfolder as a Web Service on Render. - Define your environment variables in the Render settings:
PORT=5001 MONGODB_URI=your_mongodb_connection_string JWT_SECRET=your_jwt_secret STREAM_API_KEY=your_stream_api_key STREAM_API_SECRET=your_stream_api_secret NODE_ENV=production FRONTEND_URL=https://your-app.vercel.app # URL of your Vercel deployment
- Code Change Required (CORS): Ensure
backend/src/server.jscors settings allow your Vercel frontend domain:app.use(cors({ origin: process.env.FRONTEND_URL || "http://localhost:5173", credentials: true }));
- Code Change Required (Cookies): In
backend/src/controllers/auth.controller.js, cross-origin cookies requiresameSite: "none"andsecure: true:res.cookie("jwt", token, { maxAge: 7 * 24 * 60 * 60 * 1000, httpOnly: true, sameSite: process.env.NODE_ENV === "production" ? "none" : "lax", secure: process.env.NODE_ENV === "production" });
- Import your repository on Vercel, setting the Root Directory to
frontend. - Vercel will auto-detect Vite as the framework.
- Define your environment variables in Vercel:
VITE_STREAM_API_KEY=your_stream_api_key VITE_BACKEND_URL=https://your-backend-url.onrender.com/api
- Code Change Required (Axios): Update your
frontend/src/lib/axios.jsxto dynamically target the backend URL:export const axiosInstance = axios.create({ baseURL: import.meta.env.VITE_BACKEND_URL || "http://localhost:5001/api", withCredentials: true, });
You can serve both frontend and backend on a single Render service by statically serving the production build:
- The root
package.jsoncontains abuildscript that installs dependencies and builds the Vite frontend:npm run build
- The
startscript launches the Node server:npm run start
- In
productionmode, the Express backend automatically serves the static assets located infrontend/dist. - Create a Web Service on Render, point to the root directory, set the Build Command to
npm run build, and the Start Command tonpm run start.
- Group Video Calls: Expanding 1-on-1 calls to support group meetings.
- Screen Sharing: Allowing users to broadcast their screens during active video calls.
- Push Notifications: Integrating web push notifications for incoming calls and messages.
- Custom Avatars & Profiles: Allowing richer user profiles and banner images.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the ISC License. See LICENSE for more information.