A production-grade NLP web app that scores how well a resume matches a job description, surfaces missing skills, and recommends improvements.
Architecture: FastAPI backend + custom HTML/CSS/JS frontend (no framework bloat). Uses sentence-transformers for semantic embeddings and cosine similarity for matching.
- Custom-designed UI — recruiter-friendly corporate aesthetic, light & dark mode
- Drag-and-drop PDF upload with size & filename preview
- Semantic similarity via
all-MiniLM-L6-v2(384-dim embeddings) - Animated score gauge with dynamic color (red → amber → blue → green)
- Keyword gap analysis — see what's missing vs. matched
- Actionable suggestions based on score and gaps
- Fast — ~1–2s analysis after model warmup
- Local & private — your resume never leaves your machine
resumelens/
├── backend/
│ ├── main.py # FastAPI app + REST endpoints
│ ├── nlp.py # PDF extraction, embeddings, scoring
│ └── requirements.txt # Python dependencies
└── frontend/
├── index.html # Single-page UI
├── styles.css # Design system (light + dark)
└── app.js # File handling, API calls, animations
cd "C:\path\to\resumelens"python -m venv venv
venv\Scripts\activatepip install -r backend\requirements.txt(First install takes 5–10 minutes — PyTorch is large.)
cd backend
uvicorn main:app --reload --host 0.0.0.0 --port 8000Visit http://localhost:8000 in your browser.
The first analysis will download the all-MiniLM-L6-v2 model (~80 MB) — one-time only.
┌──────────────────────────────────────────┐
│ Browser (HTML / CSS / vanilla JS) │
│ • Drag-and-drop upload │
│ • Animated score gauge │
│ • Light/dark theme toggle │
└────────────────┬─────────────────────────┘
│ POST /api/analyze
│ multipart: resume.pdf + job_description
▼
┌──────────────────────────────────────────┐
│ FastAPI (uvicorn) │
│ • /api/analyze – scoring endpoint │
│ • / – serves index.html │
│ • /static/* – CSS, JS │
└────────────────┬─────────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ NLP pipeline │
│ PyPDF2 → text │
│ sentence-transformers → embeddings │
│ scikit-learn → cosine similarity │
│ Custom tokenizer → keyword gap │
└──────────────────────────────────────────┘
Why this split? The frontend is fully decoupled from the backend — you can deploy them together (single uvicorn process, as configured) or split them later (e.g., frontend on Vercel, API on Render).
Request (multipart/form-data):
resume: PDF filejob_description: text string
Response (JSON):
{
"score": 78.4,
"label": "Strong Match",
"missing_keywords": ["docker", "kubernetes", "fastapi"],
"matched_keywords": ["python", "machine", "learning"],
"suggestions": ["…", "…"],
"resume_preview": "First 600 chars of extracted text…"
}Returns {"status": "ok"} — useful for uptime monitors.
Interactive Swagger UI auto-generated by FastAPI.
- Typography: Fraunces (display serif, with optical-size axis) + Inter Tight (body) + JetBrains Mono (technical labels)
- Palette: Warm off-white in light mode, deep navy in dark mode, with azure-700 as the single accent
- No gradients-as-decoration — gradients reserved for the brand mark and hero atmosphere
- CSS variables for the entire color system — adding new themes is trivial
- No frontend framework — keeps the bundle effectively zero, loads instantly
- LLM-based resume rewriting (OpenAI / Claude API)
- Multi-job batch comparison
- ATS simulation scoring
- Dockerfile for one-command deployment
- User accounts + history (PostgreSQL)
MIT — free to use, modify, and distribute.
Built by Muhammad Shaheer Akhtar · 2026