An AI-assisted collaborative study platform. Students find compatible study partners, chat in real time, meet in voice/video study rooms with screen sharing, schedule sessions, share notes, and get help from a Gemini-powered AI study assistant — all in one place.
Production: https://studynest.dev
Screenshots coming soon.
- 100+ REST endpoints · 100+ Socket.IO events · 20 data models
- 125 passing integration tests (Jest + Supertest, in-memory MongoDB)
- Piloted with 44 students — 86% reported high satisfaction, and 95% said the AI study assistant improved how they study
- Bilingual EN/AR Progressive Web App
- React 18 + TypeScript (strict)
- Vite 6 — build tool;
@→src/,@shared→shared/ - Tailwind CSS 3 — utility CSS with CSS-variable theme system
- TanStack Query v5 — server state cache + mutations
- React Router DOM v7 — SPA routing
- Framer Motion — animations
- React Hook Form + Zod — forms + validation
- Socket.IO Client 4 — real-time
- shadcn/ui — component primitives
- Node.js ≥ 20 + Express 4
- MongoDB via Mongoose 8 (Atlas in production)
- Socket.IO 4 — WebRTC signaling, chat, presence
- JWT (15 min access + 7 day refresh) + bcryptjs
- Upstash Redis — caching (optional, graceful fallback)
- Cloudinary — all image and file storage
- Nodemailer — transactional email (OTP, verification)
- Google Gemini API (
gemini-2.5-flashtext,gemini-2.0-flashimages)
- Node.js ≥ 20
- MongoDB (local or Atlas)
- Cloudinary account
- Google Gemini API key
- Gmail app password (for email)
- Redis / Upstash (optional)
# Install frontend dependencies
npm install
# Install backend dependencies
cd backend && npm install && cp .env.example .env
# Edit backend/.env with your own credentials — never commit real keys
cd ..
# Start both services
npm run start:dev
# Check health
npm run health
# Stop everything
npm run stop:devTerminal 1 — Backend:
cd backend
cp .env.example .env # then fill in your own credentials
npm start # or: npm run dev (nodemon auto-reload)Terminal 2 — Frontend:
npm run dev| Service | Port |
|---|---|
| Frontend (Vite) | 5175 |
| Backend API | 3001 |
| MongoDB | 27017 |
| Redis (optional) | 6379 |
Vite proxies /api and /socket.io → http://localhost:3001.
| Command | Description |
|---|---|
npm run dev |
Start Vite dev server (port 5175) |
npm run build |
Production build → dist/ |
npm run lint |
Run ESLint |
npm run preview |
Preview production build |
npm run start:dev |
Start frontend + backend together |
npm run stop:dev |
Stop all dev processes |
npm run health |
Check service health |
npm run audit:i18n |
Find missing translation keys |
| Command | Description |
|---|---|
npm start |
Production start |
npm run dev |
Start with nodemon (auto-reload) |
npm test |
Run integration tests |
npm run lint |
Run ESLint |
Both the root and backend/ directories ship a committed .env.example template. Copy each to .env and fill in your own values — .env files are gitignored and real keys are never committed. The keys below are reproduced from those templates with placeholder values.
# Server
PORT=3001
NODE_ENV=development
NODE_VERSION=20.11.0
# Database
MONGODB_URI=mongodb+srv://<user>:<pass>@<cluster>.mongodb.net/<db>?retryWrites=true&w=majority
MONGODB_DB_NAME=studynest_production
# Security
JWT_SECRET=<random-min-32-chars>
JWT_REFRESH_SECRET=<random-min-32-chars>
JWT_EXPIRE=15m
JWT_REFRESH_EXPIRE=7d
SESSION_SECRET=<random-min-32-chars>
CSRF_SECRET=<random-min-32-chars>
# CORS
CORS_ORIGIN=https://studynest.dev,https://www.studynest.dev
# Rate limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
# Cloudinary (required for image uploads)
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
# AI (Google Gemini — direct calls from Node)
GEMINI_API_KEY=your-gemini-api-key
GEMINI_MODEL=gemini-2.5-flash
GEMINI_IMAGE_MODEL=gemini-2.0-flash
# Email (Gmail SMTP)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_SECURE=false
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-gmail-app-password
EMAIL_FROM=StudyNest <your-email@gmail.com>
# Redis / Upstash (optional — server degrades gracefully without it)
UPSTASH_REDIS_REST_URL=https://your-instance.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-tokenVITE_API_BASE_URL=http://localhost:3001
VITE_GOOGLE_CLIENT_ID=your-google-oauth-client-idStudyNest/
├── src/ # React + TypeScript frontend
│ ├── components/
│ │ ├── Auth/ # Login, Signup, ForgotPassword, TwoFactorLogin
│ │ ├── common/ # Shared UI (Skeletons, NoteCard, MediaGrid, …)
│ │ ├── meeting/ # WebRTC video room + all meeting components
│ │ ├── pages/ # Route-level pages
│ │ └── ui/ # Primitives (Toast, Icon, LikeButton, …)
│ ├── contexts/ # Auth, Theme, Language, Toast, ChatHistory, Navigation, Performance
│ ├── hooks/ # Custom React hooks
│ ├── i18n/ # en/ar translations
│ ├── services/api/ # Axios client + domain API modules
│ ├── types/ # TypeScript interfaces
│ ├── utils/ # validation, bookmarks, serviceWorker
│ └── workers/ # Web Workers
├── backend/
│ ├── config/ # database, cloudinary, redis, logger
│ ├── controllers/ # Route handlers
│ ├── helpers/ # accessControl.js
│ ├── jobs/ # notificationScheduler.js
│ ├── middleware/ # auth, cache, errorHandler, performance, socketAuth
│ ├── models/ # 20 Mongoose models
│ ├── routes/ # Express routers
│ ├── services/ # email, notification, push, token, otp, streak, meetingState
│ ├── sockets/ # Socket.IO handlers
│ └── tests/ # Jest integration tests
├── shared/
│ ├── socketEvents.cjs # Canonical socket event names (single source of truth)
│ └── meetingContracts.cjs
└── public/ # Static assets (sw.js, logos, favicon)
- Partner discovery — algorithmic multi-factor matching: filter and score compatibility by subjects, level, study style, country, and schedule
- Real-time chat — DMs + group conversations; text, image, file, and voice messages (live canvas waveform, cancel/send controls); typing indicators, read receipts, pin/archive/mute; invite cards for rooms/sessions/notes
- Study sessions — schedule, join, start/end; public/partners/specific visibility; deep-link sharing
- Video meetings — instant WebRTC calls from chat; host/co-host/participant roles; HD screen share (1920×1080); voice activity indicator; in-call chat; recording signaling; heartbeat/reconnect
- Notes — markdown notes with visibility controls; likes, comments, bookmarks; file attachments up to 100 MB; deep-link sharing
- AI study assistant — Gemini-powered: chat, document & image analysis, study-plan generation, flashcards, note-title generation, voice-to-text, and an in-meeting AI panel. Gemini powers the study assistant only — partner matching uses a separate rule-based multi-factor scorer, not an LLM.
- Streaks & activity — 30-min daily goal unlocks +1 streak; tracked on all authenticated pages; 24h window; weekly activity chart; milestone notifications
- Notifications — in-app + real-time socket + browser system notifications; per-category preferences; scheduled session reminders; security events (
login_recorded,security_new_device_login,security_alert) always fire regardless of user prefs - Auth & security — JWT access tokens with refresh-token rotation, role-based access control (RBAC), email verification, and automatic account lockout on repeated failures
- 2FA — email OTP, TOTP app, SMS; trusted devices bypass 2FA
- PWA — service worker, web push tokens, offline support
Base URL: /api/v1 (also /api for backward compatibility)
All responses follow:
{ "success": true, "data": { ... } }
{ "success": false, "error": { "code": "SOME_CODE", "message": "..." } }Health checks (no auth): GET /health/startup, GET /health/ready
Full endpoint reference: see CLAUDE-REFERENCE.md §1.
All event names are defined in shared/socketEvents.cjs — never use raw strings.
Socket rooms:
user_{userId}— personal notificationsconversation_{id}— chat roomsmeeting_{id}— video call roomssession_{id}— study session rooms
Full event reference: see CLAUDE-REFERENCE.md §3.
| Layer | Platform |
|---|---|
| Frontend | Vercel (SPA, all routes → /) |
| Backend | Render.com (backend/ root, port 10000) |
| Database | MongoDB Atlas |
| Cache | Upstash Redis |
| Media | Cloudinary |
| Gmail SMTP |
cd backend && npm test125 passing tests on Jest 29 + Supertest + in-memory MongoDB. No real database needed. Tests cover auth, users, notes, sessions, messages, partners, and meeting state.
| File | Contents |
|---|---|
| CLAUDE.md | Working guide for Claude Code — architecture, conventions, common traps |
| CLAUDE-REFERENCE.md | Deep reference — all endpoints, models, socket events, types |
| ARCHITECTURE.md | System architecture diagrams and data flows |
| FEATURES.md | Full feature list with implementation status |
| AI_CONTEXT.md | AI integration details and invariants |
| DEV-SETUP.md | Development setup troubleshooting |
| DEVELOPER-GUIDE.md | Quick developer reference |
| SECURITY-ROTATION.md | Secret rotation procedures |
| GOOGLE_OAUTH_SETUP.md | Google OAuth setup guide |
- Branch from
dev(notmain) - Run
npm run lint(frontend) andcd backend && npm run lintbefore committing - Run
cd backend && npm testto verify backend tests pass - Submit PR targeting
dev
Private — all rights reserved.