Code together. Think faster.
-
Real-Time Collaboration: A real-time collaborative code editor with AI-powered assistance. Multiple users can simultaneously write, edit, and debug code in the same room β with live cursor tracking, instant code synchronization, and an AI assistant powered by Google Gemini that streams responses in real-time.
-
Scalability: Designed a stateless backend architecture by replacing in-memory state with Redis, enabling horizontal scaling across multiple server instances.
-
AI Integration: Implemented an AI assistant with streaming responses (SSE), delivering real-time incremental outputs similar to ChatGPT.
-
Distributed Architecture: Developed a Redis-based data model (room:{id}:users) as a single source of truth for user presence, ensuring consistency in distributed environments.
-
Persistence & Reliability: Built a snapshot persistence system with authenticated fetch keepalive, ensuring code is saved reliably even during page unload events.
| Feature | Description |
|---|---|
| π₯οΈ Monaco Editor | VS Code-quality editor with syntax highlighting, IntelliSense, and custom themes per language |
| π₯ Real-Time Collaboration | Multiple users edit simultaneously with live cursor positions and colored name badges |
| π€ AI Assistant (Gemini) | Ask Gemini to explain, review, fix, or optimize your code β responses stream in real-time via SSE |
| βοΈ Selection Toolbar | Select any code snippet β inline floating toolbar with Explain, Review, Fix, Optimize, and custom Ask actions |
| Run code directly in the browser (Python, JavaScript, C++, C) via Judge0 API | |
| πΈ Version History | Automatic snapshots on every run + manual save with one-click restore |
| π JWT Authentication | Secure signup/signin with bcrypt password hashing and JWT tokens |
| β‘ Redis-Backed State | Room state, user presence, and code content stored in Redis for horizontal scaling |
| π±οΈ Resizable AI Panel | Drag to resize the AI output section for a customized workspace |
| π₯ Code Download | Download your code as a properly named file (e.g., Rahul-2026-04-04.py) |
| π¨ Custom Themes | Each language has its own color-tuned Monaco theme (blue for Python, amber for JS, purple for C++, teal for C) |
| Language | Badge | Judge0 ID | Monaco Theme |
|---|---|---|---|
| JavaScript | JS |
63 | Warm amber |
| Python | PY |
71 | Deep blue |
| C++ | C++ |
54 | Purple |
| C | C |
50 | Teal |
%%{init: {'theme': 'base'}}%%
flowchart TB
subgraph Client["π₯οΈ Frontend Β· React + Vite"]
direction LR
Monaco["Monaco Editor"]
AIP["AI Panel"]
VH["Version History"]
end
subgraph HooksLayer["πͺ Hooks Layer"]
direction LR
HC["useCollaboration"]
HA["useAI"]
HP["useEditorPersistence"]
end
Client --> HooksLayer
HC <-->|"WebSocket"| SocketIO
HA <-->|"SSE Stream"| AIRoute
HP <-->|"REST + JWT"| RoomRoute
subgraph Server["βοΈ Backend Β· Express"]
MW["Middleware\nHelmet Β· CORS Β· Rate Limit Β· JWT Β· Zod"]
subgraph Core["Services"]
direction LR
SocketIO["Socket.IO Server\n+ Redis Adapter"]
AIRoute["AI Service\nGemini 2.5 Flash"]
RoomRoute["Room Service"]
CompileSvc["Compile Service"]
end
MW --> Core
end
CompileSvc -->|"HTTP"| Judge0["Judge0 API"]
AIRoute -->|"API"| Gemini["Google Gemini"]
subgraph DataStores["πΎ Data Layer"]
direction LR
PG["PostgreSQL Β· Prisma ORM\nUser Β· Room Β· Snapshot Β· AIMessage"]
RD["Redis\nRoom State Β· Presence Β· Pub/Sub"]
end
Core --> DataStores
SocketIO -.->|"horizontal scaling"| RD
%% π¨ COLOR DEFINITIONS
classDef client fill:#3b82f6,stroke:#1e40af,color:#fff
classDef core fill:#10b981,stroke:#065f46,color:#fff
classDef service fill:#f59e0b,stroke:#92400e,color:#fff
classDef realtime fill:#8b5cf6,stroke:#5b21b6,color:#fff
classDef data fill:#ef4444,stroke:#7f1d1d,color:#fff
classDef external fill:#f3f4f6,stroke:#9ca3af,color:#111
%% π― APPLY COLORS
%% Frontend
class Monaco,AIP,VH client
%% Hooks + Middleware
class HC,HA,HP,MW core
%% Services
class AIRoute,RoomRoute,CompileSvc service
%% Realtime
class SocketIO realtime
%% Data
class PG,RD data
%% External APIs
class Judge0,Gemini external
smart-code-lab/
βββ .github/
β βββ workflows/
β βββ ci.yml # CI pipeline (GitHub Actions)
βββ backend/ # Express API + Socket.IO server
βββ frontend/ # React + Vite SPA
βββ .gitignore
βββ README.md
| Technology | Version | Purpose |
|---|---|---|
| React | 19.2 | UI framework |
| Vite | 8.0 | Build tool & dev server |
| TypeScript | 5.9 | Type safety |
| TailwindCSS | 4.2 | Utility-first styling |
| Monaco Editor | 4.7 | Code editor (VS Code engine) |
| Socket.IO Client | 4.8 | Real-time WebSocket communication |
| Axios | 1.13 | HTTP client with interceptors |
| React Router DOM | 7.13 | Client-side routing |
| React Markdown | 10.1 | AI response rendering |
| Vitest | 4.1 | Testing framework |
| Testing Library | 16.3 | Component testing |
| Technology | Version | Purpose |
|---|---|---|
| Express | 5.2 | Web framework |
| TypeScript | 5.9 | Type safety |
| Prisma | 5.22 | ORM for PostgreSQL |
| PostgreSQL | β | Primary database |
| Redis | 5.11 | Session state + Socket.IO adapter |
| Socket.IO | 4.8 | Real-time WebSocket server |
| @socket.io/redis-adapter | 8.3 | Multi-server pub/sub |
| Google Generative AI | 0.24 | Gemini AI integration |
| JSON Web Token | 9.0 | Authentication |
| Bcrypt | 6.0 | Password hashing |
| Zod | 4.3 | Request validation |
| Helmet | 8.1 | Security headers |
| Express Rate Limit | 8.3 | Rate limiting |
| Jest | 30.3 | Testing framework |
| Supertest | 7.2 | HTTP assertion library |
- Node.js β₯ 20
- npm β₯ 9
- PostgreSQL (local or hosted, e.g., Neon DB)
- Redis (local or hosted, e.g., Render Redis)
- Gemini API Key β Get one here
git clone https://github.com/rah7202/smart-code-lab.git
cd smart-code-labcd backend
npm installCreate backend/.env.local:
DATABASE_URL="postgresql://user:password@localhost:5432/smartcodelab"
GEMINI_API_KEY=your_gemini_api_key
JWT_SECRET=your_jwt_secret_here_minimum_64_chars
ALLOWED_ORIGINS=http://localhost:5173
REDIS_URL=redis://localhost:6379
LOG_LEVEL=debugGenerate Prisma client and run migrations:
npx prisma generate
npx prisma migrate devStart the backend dev server:
npm run dev
# β Server starts on http://localhost:8000cd ../frontend
npm installCreate frontend/.env.local:
VITE_BACKEND_URL=http://localhost:8000Start the frontend dev server:
npm run dev
# β App opens on http://localhost:5173- Navigate to
http://localhost:5173 - Sign up for an account
- Create a room or enter an existing Room ID
- Start coding!
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
β | PostgreSQL connection string |
GEMINI_API_KEY |
β | Google Gemini API key |
JWT_SECRET |
β | Secret for signing JWT tokens (min 64 chars) |
ALLOWED_ORIGINS |
β | Comma-separated allowed CORS origins |
REDIS_URL |
β | Redis connection string |
LOG_LEVEL |
β | Log level (debug, info, warn, error) |
NODE_ENV |
β | Environment mode |
| Variable | Required | Description |
|---|---|---|
VITE_BACKEND_URL |
β | Backend server URL |
| Script | Description |
|---|---|
npm run dev |
Start dev server with hot reload |
npm run build |
Compile TypeScript to dist/ |
npm start |
Start production server |
npm test |
Run tests with coverage report |
| Script | Description |
|---|---|
npm run dev |
Start Vite dev server |
npm run build |
Type-check + build for production |
npm test |
Run tests once |
npm run test:coverage |
Run tests with coverage report |
npm run lint |
Lint all files |
GitHub Actions runs on every push/PR to main. Both jobs enforce 70% coverage thresholds for lines and functions.
backend job:
1. Checkout β Setup Node 20 β npm ci (cached)
2. npx prisma generate
3. npm test -- --coverage --ci
4. npm run build
frontend job (runs after backend passes):
1. Checkout β Setup Node 20 β npm ci (cached)
2. npm run test:coverage
3. npm run build
| Feature | Priority | Notes |
|---|---|---|
| Yjs / CRDT Integration | π΅ Next Major | Replace keystroke broadcasting with binary delta sync for better concurrency |
| Docker Compose | π‘ Medium | Redis + PostgreSQL + App in one-command setup |
| More Languages | π‘ Medium | Java, Go, Rust, etc. |
| AI Context Awareness | π΅ Future | Pass execution output to Gemini for smarter debugging |
| JWT Blacklist on Logout | π’ Easy | redis.set(blacklist:${token}) with TTL |
Rahul β github.com/rah7202
Repository β github.com/rah7202/smart-code-lab