Studi.io is a modern, collaborative study platform that brings students together in virtual study rooms. Built with real-time communication, resource sharing, and interactive whiteboards, Studi.io makes group studying productive and engaging.
🔗 Live Demo: https://studiio.netlify.app
- 🚪 Create & Join Rooms – Easily create or join public/private study rooms
- 💬 Real-time Chat – Instant messaging with Socket.IO for seamless communication
- 🔒 Privacy Control – Public or private rooms with customizable access
- 🖼️ Room Customization – Set custom names, descriptions, and avatars
- ☁️ Cloud Image Uploads – Profile and room images hosted on Cloudinary
- ⚙️ Room Management – Full CRUD operations for room owners and admins
- 👥 Member Management – Admin controls and member permissions
- 🔔 Real-time Notifications – Instant feedback with
react-hot-toast - 📱 Responsive Design – Mobile-first UI with Tailwind CSS
- 🔐 Secure Authentication – JWT-based auth with access/refresh tokens
- 📧 Email Service – OTP verification and notifications via SendGrid
- 📝 Collaborative Whiteboard – Real-time drawing and note-taking
- 🗂️ ResourceHub – Centralized document and link management
- 🎥 Video Chat – Built-in video conferencing
- 📊 Study Analytics – Track study time and productivity
- 🔔 Push Notifications – Browser push notifications for updates
| Technology | Purpose |
|---|---|
| React 18 | UI framework with hooks and modern features |
| TypeScript | Type-safe JavaScript |
| Tailwind CSS | Utility-first CSS framework |
| Redux Toolkit | State management with Redux Persist |
| React Router | Client-side routing |
| Socket.IO Client | Real-time WebSocket communication |
| Axios | HTTP client with interceptors |
| Lucide React | Beautiful icon library |
| React Hot Toast | Toast notifications |
| Vite | Lightning-fast build tool |
| Technology | Purpose |
|---|---|
| Node.js | JavaScript runtime |
| Express.js | Web framework |
| MongoDB | NoSQL database |
| Mongoose | MongoDB ODM with schemas |
| Socket.IO | Real-time bidirectional communication |
| JWT | JSON Web Tokens for authentication |
| bcrypt | Password hashing |
| Cloudinary | Cloud-based image storage |
| SendGrid | Email delivery service |
| Multer | File upload handling |
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │◄───────►│ Server │◄───────►│ MongoDB │
│ (React) │ HTTP │ (Express) │ CRUD │ (Database) │
└─────────────┘ └──────────────┘ └─────────────┘
▲ ▲
│ │
│ WebSocket │
└───────────────────────┘
Real-time Updates
- Authentication Layer: JWT-based with refresh token rotation
- Real-time Layer: Socket.IO for instant messaging and presence
- Storage Layer: MongoDB for data, Cloudinary for media
- Email Layer: SendGrid for OTP verification and notifications
- Node.js v18+ and npm/yarn
- MongoDB Atlas account or local MongoDB
- Cloudinary account for image storage
- SendGrid account for email service
git clone https://github.com/yamiSukehiro2907/studi.io.git
cd studi.iocd server
npm installCreate .env file in server/ directory:
PORT=8000
CONNECTION_STRING=your_mongodb_connection_string
ACCESS_TOKEN_SECRET=your_access_token_secret
REFRESH_TOKEN_SECRET=your_refresh_token_secret
ACCESS_TOKEN_EXPIRATION=3600000
REFRESH_TOKEN_EXPIRATION=604800000
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
EMAIL_USER=[email protected]
SENDGRID_API_KEY=your_sendgrid_api_key
NODE_ENV=production
ALLOWED_ORIGINS=http://localhost:5173,https://studiio.netlify.appcd ../client
npm installCreate .env file in client/ directory:
VITE_API_BASE_URL=http://localhost:8000Backend:
cd server
npm run devServer runs on http://localhost:8000
Frontend:
cd client
npm run devClient runs on http://localhost:5173
Backend:
cd server
npm startFrontend:
cd client
npm run build
npm run previewstudi.io/
├── client/ # Frontend React application
│ ├── src/
│ │ ├── api/ # API service functions
│ │ ├── assets/ # Images and static files
│ │ ├── components/ # Reusable React components
│ │ │ ├── Main/ # Main content components
│ │ │ ├── Room/ # Room-related components
│ │ │ ├── Settings/ # Settings modal components
│ │ │ ├── SideBar/ # Sidebar components
│ │ │ ├── chat/ # Chat components
│ │ │ └── common/ # Shared components
│ │ ├── config/ # Configuration files
│ │ │ ├── schema/ # TypeScript interfaces
│ │ │ ├── axiosConfig.ts
│ │ │ └── socket.ts
│ │ ├── hooks/ # Custom React hooks
│ │ ├── pages/ # Page components
│ │ ├── redux/ # Redux store and slices
│ │ │ ├── slices/
│ │ │ └── store.ts
│ │ ├── App.tsx # Main App component
│ │ └── main.tsx # Entry point
│ ├── .env # Environment variables
│ └── package.json
│
├── server/ # Backend Node.js application
│ ├── config/ # Configuration files
│ │ ├── cloudinary.config.js
│ │ ├── mail.config.js
│ │ ├── mongoDB.config.js
│ │ └── multer.js
│ ├── constants/ # Constants and utilities
│ │ ├── otp.generate.js
│ │ ├── token.js
│ │ └── username.create.js
│ ├── controllers/ # Route controllers
│ │ ├── auth.controller.js
│ │ ├── message.controller.js
│ │ ├── otp.controller.js
│ │ ├── studyroom.controller.js
│ │ └── user.controller.js
│ ├── handler/ # Socket.IO handlers
│ │ └── socketHandler.js
│ ├── middleware/ # Express middleware
│ │ ├── socketAuth.js
│ │ └── validation.js
│ ├── models/ # Mongoose models
│ │ ├── message.model.js
│ │ ├── otp.model.js
│ │ ├── resource.model.js
│ │ ├── section.model.js
│ │ ├── studyRoom.model.js
│ │ └── user.model.js
│ ├── routers/ # Express routes
│ │ ├── auth.route.js
│ │ ├── message.route.js
│ │ ├── otp.route.js
│ │ ├── room.route.js
│ │ └── user.route.js
│ ├── .env # Environment variables
│ ├── index.js # Server entry point
│ └── package.json
│
└── README.md # This file
sequenceDiagram
participant User
participant Client
participant Server
participant Database
User->>Client: Sign Up
Client->>Server: POST /auth/register
Server->>Database: Create User
Server->>User: Send OTP Email
User->>Client: Enter OTP
Client->>Server: POST /otp/verify-otp
Server->>Database: Verify & Update User
Server->>Client: Success Response
User->>Client: Login
Client->>Server: POST /auth/login
Server->>Database: Verify Credentials
Server->>Client: Set Access & Refresh Tokens
Client->>Client: Store User in Redux
| Event | Payload | Description |
|---|---|---|
join-room |
{ roomId } |
Join a study room |
sendMessage |
{ roomId, content } |
Send a message |
leave-room |
{ roomId } |
Leave a room |
| Event | Payload | Description |
|---|---|---|
newMessage |
Message |
New message received |
user-joined |
{ userId, userName } |
User joined room |
user-left |
{ userId, userName } |
User left room |
messageError |
{ message } |
Error occurred |
- Password Hashing: bcrypt with 10 salt rounds
- JWT Tokens: Separate access (1h) and refresh (7d) tokens
- HTTP-Only Cookies: Tokens stored securely
- CORS Protection: Configured for specific origins
- Input Validation: Server-side validation for all inputs
- Rate Limiting: Protection against brute force attacks
- XSS Protection: Sanitized user inputs
- Email Verification: Required for account activation
- Socket Authentication: JWT verification for WebSocket connections
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a 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
- Follow the existing code style
- Write meaningful commit messages
- Update documentation for new features
- Add tests for new functionality
- Ensure all tests pass before submitting PR
Found a bug or have a feature idea? Please open an issue on GitHub Issues.
When reporting bugs, please include:
- Clear description of the issue
- Steps to reproduce
- Expected vs actual behavior
- Screenshots (if applicable)
- Browser/OS information
Register a new user
{
"name": "John Doe",
"email": "[email protected]",
"password": "securePassword123"
}Login with email/username
{
"identifier": "[email protected]",
"password": "securePassword123"
}Logout current user (clears tokens)
Refresh access token using refresh token
Create a new study room (requires auth)
{
"name": "Physics Study Group",
"description": "Preparing for finals"
}Get all rooms user is a member of (requires auth)
Search public rooms (requires auth)
Join a public room (requires auth)
Update room details (requires auth, owner/admin only)
Delete a room (requires auth, owner only)
Get paginated messages for a room (requires auth)
Get current user profile (requires auth)
Update user profile (requires auth, supports multipart/form-data)
Change password with current password (requires auth)
- Build the project:
npm run build - Deploy the
distfolder to Netlify - Set environment variable:
VITE_API_BASE_URL=your_backend_url
- Push code to GitHub
- Connect repository to hosting platform
- Set all environment variables
- Deploy with Node.js environment
- Code Splitting: React lazy loading for routes
- Image Optimization: Cloudinary automatic optimization
- Caching: Redux Persist for offline support
- Debouncing: Search queries debounced by 500ms
- Pagination: Messages paginated (50 per page)
- Connection Pooling: MongoDB connection optimization
- Gzip Compression: Reduced payload sizes
- GitHub Repository: https://github.com/yamiSukehiro2907/studi.io
- Live Demo: https://studiio.netlify.app
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Vimal Yadav
- GitHub: @yamiSukehiro2907
- Email: [email protected]
Need help? Reach out:
- Email: [email protected]
- Create an issue: GitHub Issues
- Join our community: Discussions
Made with ❤️ by the Studi.io Team
⭐ Star us on GitHub — it motivates us a lot!
