Welcome to the comprehensive guide for setting up, building, and deploying StreamifyVideoCalls—a full-stack web application with video calling and messaging features built using the MERN stack and Stream's SDKs.
This document serves as an exhaustive reference covering both backend and frontend configurations, architecture details, routing logic, and deployment steps.
Streamify is a video calling and text chat platform divided into two main environments:
- Frontend: A React application powered by Vite, utilizing modern libraries for data fetching, state management, and styling.
- Backend: An Express server handling authentication routes, MongoDB interactions, and Stream service integrations.
- Authentication: User Registration -> Onboarding Details -> Login -> Generate JWT Token.
- Social Mechanics: Discover Recommended Users, Send Friend Requests, Accept Friend Requests.
- Chat & Video via Stream: Users obtain tokens from the backend to securely interact with the Stream.io infrastructure directly from the frontend.
- Framework: React (Bootstrapped with Vite
npm create vite@latest) - Routing:
react-router-dom(v7+) - Styling:
tailwindcss(v3) &daisyui(v4) - State Management:
zustand(For global theming state) - Data Fetching:
@tanstack/react-query&axios - Notifications:
react-hot-toast - Chat/Video SDK:
stream-chat,stream-chat-react
- Runtime: Node.js
- Framework: Express.js
- Database: MongoDB (managed via
mongoose) - Authentication:
bcrypt(password hashing),jsonwebtoken(JWT for stateless sessions),cookie-parser - Environment:
dotenv - Cross-Origin Requests:
cors - Video/Chat Service:
stream-chat(Server SDK)
- Create a
backendfolder. - Run
npm init -yinside to create a package file. - Install dependencies:
npm install express bcrypt jsonwebtoken cookie-parser cors dotenv mongoose stream-chat
- Update
server.jswithin thesrc/directory to serve as the main entry point:- Configure Express logic.
- Register route handlers (
app.use('/api/auth', authRoutes), etc.).
Generate and declare following keys at the root of the backend folder:
- Database URI (MongoDB Atlas).
- Secret strings for Session Encryption.
- Stream SDK connection secrets.
PORT=5001
MONGODB_URI=your_mongo_cloud_atlas_url
JWT_SECRET=generate_using_openssl
STREAM_API_KEY=your_stream_key
STREAM_API_SECRET=your_stream_secret
NODE_ENV=development(Tip: To get a secure random key for your JWT secret, run openssl rand -base64 32 via terminal)
- Connect using
mongooselocated insrc/lib/db.js. - Export a
connectDB()wrapper function and invoke this asynchronously before Express callsapp.listen(). - Note: Ensure IP access lists inside MongoDB Atlas network access points are opened up (
0.0.0.0/0) during development.
The controllers located in src/controllers/auth.controller.js act on routes defined in src/routes/auth.route.js.
- Signup Phase: Evaluate user payload, check duplicates.
- Password Hashing: We use Mongoose
pre('save')hooks within theUser.jsschema models to automatically hash outgoing passwords usingbcrypt. - Token Creation: Valid authenticated sessions generate a JSON Web Token injected into an HTTP-Only secure cookie format.
- Stream App Synchronization: Instantly map new users via the
stream.jscustom wrapper logic which hooks intoserverClient.upsertUser.
- Initialize the
StreamChatclient instance in your backend (lib/stream.js). - Implement Token Generation route for user sessions (
http://localhost:5001/api/chat/token). Clients require this token securely from your server to speak functionally with the Stream WebSocket APIs.
- Created middleware
auth.middleware.jsto extract and verify thejwtcookie. - Fetches user data dynamically via
req.user.
Initialize using npm create vite@latest . inside the frontend folder, choose React + JavaScript.
- Follow current guidelines to configure
tailwind.config.js. - Make sure to target your
./src/**/*.{js,jsx,ts,tsx}files in the Tailwind content. - Include Daisy UI
require('daisyui')within plugins array. - Assign theme globally using DaisyUI’s native wrapper
<div data-theme="theme-name">.
- Wrap the core
<App />application with<BrowserRouter>viamain.jsx. - Implement page structures inside a dedicated
src/pagesfolder:HomePage,SignUpPage,LoginPage- Render components dynamically utilizing standard
<Routes>wrapper mechanisms.
Streamify leverages TanStack Query (React Query) for predictable, declarative API data requests without manually managing useEffect lifecycles.
- QueryClient Provider: Encase the
<App />withinQueryClientProviderwithinmain.jsx. - Custom Hooks Integration: Encapsulate API checks (e.g., verifying logged-in user via
/auth/me) utilizinguseQueryunder standardized query keys (['authUser']). - Form submissions for Login / Sign-up utilize
useMutationimplementations mapped alongside centralized Axios instances. - Avoid redundant manual loading states by depending on TanStack Query abstractions (
isLoading,error).
Manage standard visual themes uniformly across the application via Zustand.
- Create
src/store/useThemeStore.js. - Register theme parameters (
theme,setTheme()) onto the globally accessible state tree. - Access data properties universally via the
useThemeStore()customized consumer.
npm install stream-chat stream-chat-react- Import CSS declarations natively globally (
import "stream-chat-react/dist/css/v2/index.css";) within themain.jsxscope before your primaryindex.css. - Bootstrap
Chat,Channel,Window,ChannelHeader,MessageList,MessageInput, andThreadcontainers.
Deploying Streamify involves consolidating both frontend builds + backend executable instances natively beneath a unified package process inside a singular environment.
Create an entry-level package.json sitting in the Root Directory pointing directly alongside the frontend and backend structures. Establish these build scripts to orchestrate the deployment workflow:
"scripts": {
"start": "npm run start --prefix backend",
"build": "npm install --prefix backend && npm install --prefix frontend && npm run build --prefix frontend"
}Configure the backend server to natively serve React frontend-compiled dist assets running actively specifically when targeting NODE_ENV=production. Modifying server.js:
import path from "path";
const __dirname = path.resolve();
// Only after defining functional API routes.
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../frontend/dist")));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../frontend", "dist", "index.html"));
});
}Ensure dynamically mapped URLs within your centralized Axios integration logic shift automatically depending on active runtimes natively:
const BASE_URL = import.meta.env.MODE === "development" ? "http://localhost:5001/api" : "/api";
export const axiosInstance = axios.create({
baseURL: BASE_URL,
withCredentials: true, // Necessary if cookie logic relies on credentials.
});- Commit all files natively mapped to a designated GitHub Repo (verify
.envandnode_modulesfolders remain appropriately excluded via.gitignoreglobally positioned within root). - Connect rendering configurations seamlessly directly leveraging chosen repositories.
- Set the build command to
npm run buildnatively inside Render. - Establish the start execution command as
npm run start. - Map necessary backend Environmental mappings cleanly specifically inside Render Settings (no need mapping
NODE_ENV=productionexplicitly as Render inherently establishes this natively).
- Express Documentation - Essential backend routing.
- Mongoose Middleware (Hooks) - Crucial for database schema password hashing pre-hooks.
- Stream Video & Chat Platform Documentation - The underlying core framework handling scalable WebRTC and messaging.
- Specifically: Stream Chat React SDK
- Tailwind CSS (v3) & DaisyUI - Detailed setup references for specific application styling components.
- React Router Setup (v7) - Fundamental navigation boundaries.
- TanStack React Query - Server-state orchestration techniques to maintain predictable auth payloads.
- Zustand GitHub Docs - The specific reference behind lightweight global themed parameters.
- Render Docs (Static Sites & Node.js Deployments) - Deployment integration references.