The Problem
I had 50+ GitHub repositories and absolutely no idea which ones were worth showing to recruiters or adding to my portfolio.
Some were full products, some were half-finished experiments, and some were just "I was learning this on a Sunday" repos.
So I built a tool to solve this — GitHub Portfolio Analyzer.
What It Does
The app has two completely separate modes:
📊 Tab 1: Normal Analyze (Metadata)
This mode uses only GitHub API data — no AI, instant results.
Every repo gets scored from 0 to 100 based on:
Score = Stars (max 40)
+ Activity/last push (max 25)
+ Completeness: description, homepage, topics (max 25)
+ Community: forks + watchers (max 20)
Then it auto-categorizes:
- 📦 Product — Score ≥ 50 or has live demo + stars
- 🛠️ Project — Score ≥ 22 or recently active
- 🧪 Experiment — Everything else
You also get:
- 🏆 Top 3 "Most Impressive" repos with podium
- 💎 Showcase Picker — portfolio-worthy repos highlighted
- Filter by category, search by name, sort by score/stars/date
🤖 Tab 2: Deep AI Analyze (Google Gemini)
This mode reads each repo's README and sends it to Gemini 1.5 Flash for an honest review.
For each repo, AI returns:
- AI Score (0-100)
- Category: Product / Project / Experiment / Learning
- 2-3 sentence summary
- Strengths & Improvements
- Showcase Potential: High / Medium / Low
- Tech Stack detection
The two tabs are completely separate — no mixing of metadata scores and AI scores.
Tech Stack
Next.js 15 — App Router
TypeScript — Strict mode, zero `any`
Tailwind CSS — All styling
GitHub REST API — Fetch repos + README files
Google Gemini — Free tier AI analysis
Key Technical Decisions
1. Sequential fetch instead of parallel
// ❌ Old approach - hard to debug errors
const [user, repos] = await Promise.all([fetchUser(), fetchAllRepos()])
// ✅ New approach - validate credentials first
const user = await fetchUser(username, token)
const repos = await fetchAllRepos(username, token)
2. Rate limit safe AI analysis
Gemini free tier = 15 requests/minute. So I added a 6 second gap between each repo analysis with a progress bar and stop button.
3. Using Bearer instead of token prefix
// ❌ Old (deprecated)
headers["Authorization"] = `token ${token}`
// ✅ New (recommended)
headers["Authorization"] = `Bearer ${token}`
headers["X-GitHub-Api-Version"] = "2022-11-28"
What I Learned
-
GitHub fine-grained tokens are strict about permissions —
affiliation=ownercauses 422 errors, usetype=allinstead -
Gemini model names matter —
gemini-2.0-flash-litewithv1betais the most reliable free tier option - Mobile coding is hard but possible — this entire project was built on a mobile phone using GitHub Codespaces 😅
Try It
🔗 Live Demo: https://github-portfolio-analyzer.vercel.app
⭐ GitHub: https://github.com/Nischayb99/github-portfolio-analyzer
You'll need:
- GitHub username (for public repos)
- GitHub Personal Access Token (for private repos — free, read-only)
- Google Gemini API key (for AI analysis — free tier)
What's Next?
- [ ] Backend + auth to save analysis history
- [ ] Team/org support
- [ ] Export as PDF report
- [ ] Compare with other developers
Would love your feedback! What feature would you find most useful?
Built with ❤️ by Nischay Bandodiya — Full-stack developer from Indore, India
This article was originally published by DEV Community and written by Nischay Bandodiya.
Read original article on DEV Community