Practice. Get Guided. Get Better.
An AI-powered coding interview prep platform that teaches you why patterns work — not just how to memorize them.
You can grind 500 LeetCode problems and still freeze in interviews. Watching someone else's solution doesn't teach you to think — it teaches you to copy.
CodeMate is different:
| Traditional Platforms | CodeMate |
|---|---|
| Memorize solutions on YouTube | Understand why the pattern works |
| Get stuck with nowhere to turn | AI guidance that teaches, not tells |
| Random problem grinding | Structured path through what matters |
| Generic problems | Company-specific problem generation |
Generate unlimited, fresh coding problems on demand. Choose your topic, difficulty, company style, and real-world context — and get a unique problem with full test cases and starter code in seconds.
- 18 topics: Arrays, Hash Maps, Trees, Graphs, Dynamic Programming, and more
- Company styles: Google, Amazon, Meta, Apple, Microsoft, Netflix, Uber, Airbnb
- Real-world contexts: Fintech, Logistics, Healthcare, Gaming, Social Media, etc.
- Modes: Open practice or timed interview simulation (45 min)
- Powered by: Groq Llama 3.3 70B — fast, accurate, fully structured output
CodeMate's AI mentor analyzes your specific code and gives Socratic hints — never the answer.
Every guidance response follows this structure:
- What you've got right — acknowledge correct reasoning
- Something to consider — surface a gap without giving it away
- Next step — a concrete, actionable nudge
- Guiding question — make you think deeper
Delivered via real-time streaming (SSE), so feedback appears as it's generated.
Monaco Editor — the same engine powering VS Code — with:
- 5 languages: TypeScript, JavaScript, Python, Java, C++
- Vim mode toggle
- Configurable font size and tab width
- Keyboard shortcuts:
Ctrl+Enterto run,Ctrl+Shift+Enterto submit - Live test case panel with custom test case input
Curated curriculum with prerequisite unlocking — so you master fundamentals before tackling advanced topics.
- Linear progression (Arrays → Sliding Window → Dynamic Programming)
- Per-topic progress tracking
- Unlocks next module only after completing prerequisites
- Daily streak tracking
- 364-day activity heatmap
- Per-topic mastery breakdown
- Difficulty acceptance rates
- Full submission history
Filter the problem bank by company to laser-focus your prep for specific interview loops.
| Layer | Technology |
|---|---|
| Framework | Next.js 14.2 (App Router, Server Components) |
| Language | TypeScript 5.7 (strict mode) |
| Styling | Tailwind CSS 3.4 + CSS variables (dark/light) |
| Animations | Framer Motion |
| Code Editor | Monaco Editor 4.7 |
| State Management | Zustand 5 |
| Database | PostgreSQL via Supabase + Prisma ORM 5.22 |
| Authentication | Supabase Auth (email + Google OAuth) |
| AI / LLM | Groq SDK (Llama 3.3 70B Versatile) |
| Markdown | React Markdown + Remark GFM |
| Validation | Zod |
| Charts | Recharts |
| Icons | Lucide React |
codemate/
├── app/
│ ├── (marketing)/ # Public landing page
│ ├── (auth)/ # Sign in / Sign up (Supabase Auth UI)
│ ├── (app)/ # Protected workspace
│ │ ├── dashboard/ # Stats, streaks, daily challenge
│ │ ├── generate/ # AI problem generator
│ │ ├── home/ # Workspace hub
│ │ ├── paths/ # Learning paths + topic modules
│ │ ├── problems/ # Browse + solve workspace
│ │ ├── profile/ # Public user profiles
│ │ └── settings/ # User preferences
│ └── api/
│ ├── generate/ # POST — AI problem generation (Groq)
│ ├── guide/ # POST — Streaming AI guidance (SSE)
│ ├── problems/ # GET/POST — problem CRUD + filtering
│ ├── submissions/ # POST — code execution + submission
│ ├── dashboard/ # GET — user stats
│ ├── paths/ # GET — learning paths
│ ├── users/ # GET — user profiles
│ └── auth/ # Supabase auth helpers
├── components/
│ ├── editor/ # CodeEditor, AIGuideDrawer, TestCasePanel
│ ├── generate/ # GenerateForm
│ ├── problems/ # ProblemWorkspace, ProblemCard, ProblemTable
│ ├── paths/ # PathCard, TopicModule
│ ├── profile/ # ActivityHeatmap, RadarChart, ProgressRing
│ ├── layout/ # NavBar, Sidebar, Footer
│ ├── shared/ # EmptyState, Skeleton, UserAvatar, Logo
│ └── ui/ # Button, Card, Input, Badge, Textarea
├── lib/
│ ├── data/ # DB query functions + demo fallback data
│ ├── execution/ # Code execution (JS/TS in-process, Python)
│ ├── stores/ # Zustand editor store
│ └── supabase/ # Client + server Supabase instances
├── prisma/
│ ├── schema.prisma # Database schema
│ └── migrations/ # Migration history
├── types/
│ └── index.ts # Shared TypeScript types
└── constants/ # App-wide constants
model UserProfile {
id String // Supabase Auth user ID
username String @unique
streak Int
lastActive DateTime
// bio, location, github, linkedin, avatar...
}
model Problem {
slug String @unique
number Int @unique @default(autoincrement())
title String
description String // HTML
difficulty String // Easy | Medium | Hard
tags String[]
companies String[]
isAIGenerated Boolean
starterCode Json // { typescript, python, javascript, java, cpp }
hints String[]
testCases TestCase[]
submissions Submission[]
}
model Submission {
id String
userId String
problemId String
code String
language String
status String // Accepted | Wrong Answer | Runtime Error
runtime Int?
memory Int?
}
model LearningPath {
slug String @unique
title String
topics TopicModule[]
}
model TopicModule {
slug String @unique
prerequisiteId String? // unlock system
problems Problem[]
}git clone https://github.com/Doondi-Ashlesh/CodeMate.git
cd CodeMate
npm installcp .env.example .env.localFill in all required values (see Environment Variables below).
# Generate Prisma client
npm run prisma:generate
# Run migrations against your Supabase PostgreSQL instance
npm run prisma:migratenpm run devOpen http://localhost:3000 in your browser.
Create a .env.local file at the project root:
# ──────────────────────────────────────────────
# DATABASE (Supabase PostgreSQL)
# ──────────────────────────────────────────────
# Connection pooler URL (for runtime queries)
DATABASE_URL=postgresql://postgres:[PASSWORD]@[POOLER-HOST]:6543/postgres?pgbouncer=true&connection_limit=1
# Direct URL (for Prisma migrations only)
DIRECT_URL=postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
# ──────────────────────────────────────────────
# SUPABASE AUTH
# ──────────────────────────────────────────────
NEXT_PUBLIC_SUPABASE_URL=https://[PROJECT-REF].supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# ──────────────────────────────────────────────
# AI — GROQ (Problem generation + Guidance)
# ──────────────────────────────────────────────
GROQ_API_KEY=gsk_...
# ──────────────────────────────────────────────
# PHASE 2 (Optional — Code Execution)
# ──────────────────────────────────────────────
JUDGE0_API_URL=
JUDGE0_API_KEY=| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | Supabase connection pooler URL (pgbouncer) |
DIRECT_URL |
Yes | Supabase direct DB URL (Prisma migrations) |
NEXT_PUBLIC_SUPABASE_URL |
Yes | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Yes | Supabase anonymous key |
GROQ_API_KEY |
Yes | Groq API key for Llama 3.3 70B |
JUDGE0_API_URL |
No | Judge0 instance URL (Phase 2) |
JUDGE0_API_KEY |
No | Judge0 API key (Phase 2) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/generate |
Optional | Generate an AI problem |
POST |
/api/guide |
Optional | Stream AI guidance (SSE) |
GET |
/api/problems |
No | List/filter problems |
GET |
/api/problems/[slug] |
No | Get problem detail |
POST |
/api/submissions |
Yes | Run or submit code |
GET |
/api/dashboard |
Yes | User stats + activity |
GET |
/api/paths |
No | List learning paths |
GET |
/api/paths/[slug] |
No | Path with topic modules |
GET |
/api/users/[username] |
No | Public user profile |
GET |
/api/users/me |
Yes | Current auth user |
POST |
/api/auth/ensure-profile |
Yes | Sync Supabase → DB profile |
// Request
{
"topic": "Dynamic Programming",
"difficulty": "Medium",
"company": "Google",
"context": "Fintech",
"mode": "practice"
}
// Response
{ "slug": "dp-coin-change-variant-1234" }// Request
{
"problemSlug": "two-sum",
"userCode": "function twoSum(nums, target) { ... }",
"language": "typescript",
"submissionHistory": []
}
// Stream response — newline-delimited JSON
data: {"text": "**What you've got right:** "}
data: {"text": "Your nested loop correctly checks all pairs..."}
data: [DONE]// Request
{
"action": "run",
"slug": "two-sum",
"language": "typescript",
"code": "function twoSum(...) { ... }",
"customCases": []
}
// Response
{
"result": {
"status": "Accepted",
"runtime": 42,
"memory": 128,
"output": [...]
},
"submissionId": "sub_abc123"
}npm run dev # Start development server (localhost:3000)
npm run build # Build for production (generates Prisma client first)
npm run start # Start production server
npm run lint # Run ESLint
npm run format # Run Prettier
npm run ts:check # TypeScript type-check
npm run prisma:generate # Regenerate Prisma client from schema
npm run prisma:migrate # Apply pending migrations
npm run db:studio # Open Prisma Studio (visual DB browser)- AI problem generation (Groq Llama 3.3 70B)
- Monaco code editor (5 languages, Vim mode)
- Streaming AI guidance (SSE)
- Problem bank with filtering (topic, difficulty, company)
- Structured learning paths with prerequisite unlocking
- User authentication (email + Google OAuth)
- Dashboard with streak, heatmap, and submission history
- Public user profiles
- Company-specific problem targeting
- Judge0 code execution (server-side sandboxed runners for all languages)
- Real-time test case output with diff viewer
- Collaborative problem solving (rooms)
- Interview simulation mode with timer and pressure scoring
- Community problem contributions
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
# 1. Fork the repo and clone your fork
git clone https://github.com/YOUR_USERNAME/CodeMate.git
# 2. Create a feature branch
git checkout -b feat/your-feature-name
# 3. Make changes, then lint and type-check
npm run lint && npm run ts:check
# 4. Commit using conventional commits
git commit -m "feat: add heatmap to profile page"
# 5. Open a pull request against mainPlease follow the existing code style — TypeScript strict, no any, components under 150 lines.
MIT © Doondi Ashlesh