Screen candidates with AI — not bias.
A static web app that extracts, compresses, and analyzes resumes against job descriptions using ScaleDown and Google Gemini APIs.
| Feature | Description |
|---|---|
| PDF Resume Parsing | Client-side text extraction using PDF.js — no uploads to any server |
| Context Compression | ScaleDown API reduces resume text to only JD-relevant content |
| Compression Stats | Shows % compressed and tokens saved after each screening run |
| AI Scoring (0–100) | Gemini rates candidates based on job description fit |
| Bias Audit | Flags potential bias triggers (gender, age, ethnicity indicators) |
| Culture Fit Assessment | Evaluates communication style, teamwork, and company value alignment |
| Interview Questions | Auto-generates 3 tailored behavioral interview questions |
| Offer Letter Draft | AI-generated offer letter template with role details from the JD |
| Model Selection | Choose any Gemini LLM from a dynamically fetched list |
| Dark / Light Theme | System preference auto-detection with manual toggle |
| Mobile Responsive | Optimized layout for phones and tablets |
| Privacy-First | API keys stored in localStorage, never sent to any third-party |
📄 PDF Resumes + 📋 Job Description
⬇️ Step 1 — PDF.js extracts raw text from each resume
Raw Resume Text + Job Description
⬇️ Step 2 — ScaleDown API compresses text to JD-relevant summary
Compressed Summary + Job Description
⬇️ Step 3 — Google Gemini API analyzes and scores the candidate
✅ Score (0–100) · 📝 Analysis · ⚖️ Bias Audit · 🤝 Culture Fit · ❓ Interview Questions · 📨 Offer Letter
⬇️ Results ranked and displayed
📊 Ranked Candidate Dashboard
Each candidate goes through three sequential steps:
PDF.js extracts raw text from uploaded resumes entirely in the browser. No files are uploaded to any server.
// PDF.js v5 loaded as an ES module
import * as pdfjsLib from 'https://cdnjs.cloudflare.com/.../pdf.min.mjs';
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const content = await page.getTextContent();
fullText += content.items.map(item => item.str).join(' ');
}The raw resume text is sent to ScaleDown along with a prompt derived from the Job Description. ScaleDown compresses it into a concise, JD-relevant summary.
Endpoint: POST https://api.scaledown.xyz/compress/raw/
Headers:
x-api-key: <your-scaledown-key>
Content-Type: application/json
Request Body:
{
"context": "<full resume text>",
"prompt": "This is a resume. The Job Description is: <JD excerpt>... Extract key skills, experience, and education relevant to the JD. Identify any potential bias triggers. Keep it concise for an ATS.",
"model": "gpt-4o",
"scaledown": { "rate": "auto" }
}Response: Returns compressed_prompt — the condensed resume summary.
Why compress? Raw resumes can be thousands of tokens. Compression reduces noise, lowers API costs, and keeps the Gemini prompt focused on what matters. After screening, the app displays a compression stats bar showing the % saved and estimated tokens saved across all resumes.
The compressed summary + full JD are sent to the user-selected Gemini model. The model returns a structured JSON analysis.
Endpoint: POST https://generativelanguage.googleapis.com/v1beta/models/<model>:generateContent?key=<key>
Request Body:
{
"contents": [{ "parts": [{ "text": "<prompt with JD + compressed resume>" }] }],
"generationConfig": { "responseMimeType": "application/json" }
}Response (JSON):
{
"score": 85,
"summary": "**Strengths:** 5+ years in React... **Weaknesses:** No backend experience...",
"bias_report": "No significant bias indicators detected...",
"culture_fit": "**Strong Fit** — demonstrates clear teamwork and leadership traits...",
"questions": "1. Tell me about a time you led a cross-functional team...",
"offer_letter": "Dear [Candidate], We are pleased to offer you the position of..."
}Available models are fetched dynamically from Google's API. The list is refined for usability:
- Capability Filter: Only models supporting
generateContent(actual LLMs) are shown. - Strict Exclusion: Non-chat models (vision, audio, tts, robotics, embedding, computer-use) are hidden.
- A–Z Sorting: Models are listed in alphabetical order for consistent and predictable navigation.
Endpoint: GET https://generativelanguage.googleapis.com/v1beta/models?key=<key>
You need two API keys. Enter them via the ⚙️ Settings panel in the app.
| Key | Provider | Purpose | Get it from |
|---|---|---|---|
| ScaleDown | ScaleDown | Resume text compression | scaledown.ai |
| Gemini | AI analysis & scoring | aistudio.google.com |
Storage: Keys are saved in your browser's
localStorageand are only sent to the respective API endpoints. They are never stored on any remote server.
| Layer | Technology |
|---|---|
| Structure | HTML5 (Semantic) |
| Styling | CSS3 (Vanilla — Glassmorphism, CSS Grid, Custom Properties) |
| Logic | JavaScript ES6+ |
| PDF Parsing | PDF.js v5.4 |
| Markdown Rendering | Marked.js v16.3 |
| Icons | Font Awesome v7.0 |
| Typography | Inter (Google Fonts) |
Note: This app uses ES modules, so it must be served over HTTP — opening
index.htmldirectly viafile://won't work.
git clone https://github.com/<your-username>/RecruitAI.git
cd RecruitAI
npx -y serve .Then open http://localhost:3000 in your browser.
Alternative local servers:
# Python
python -m http.server 8000
# VS Code — install the "Live Server" extension and click "Go Live"- Click ⚙️ Settings and enter your API keys (ScaleDown + Gemini)
- Select a Gemini model from the dropdown
- Paste a Job Description, upload resumes (PDF), and click Start Screening
- Push all files to a GitHub repository
- Go to Settings → Pages
- Set the source branch (e.g.,
main) and root (/) - Your site will be live at
https://<username>.github.io/RecruitAI/
RecruitAI/
├── index.html # Main HTML structure with semantic sections
├── style.css # Glassmorphism UI, themes, responsive layout
├── script.js # Application logic, API calls, state management (ES module)
├── logo.png # Application logo and favicon
├── LICENSE # MIT License
├── README.md # This file
├── docs/ # Detailed documentation
│ ├── ARCHITECTURE.md
│ ├── API_REFERENCE.md
│ ├── SETUP_GUIDE.md
│ └── FEATURES.md
├── demo/ # Sample job description and resumes for testing
│ ├── Job_Description.txt
│ └── resumes/ # 5 pre-generated PDF resumes
| Document | Description |
|---|---|
| Architecture | System overview, data flow, state management, and design decisions |
| API Reference | ScaleDown & Gemini endpoints, request/response formats, prompt template |
| Setup Guide | Installation, local servers, API key setup, deployment, troubleshooting |
| Features | In-depth documentation of all 12 features |
Contributions are welcome! Here's how to get started:
- Fork this repository
- Clone your fork:
git clone https://github.com/<your-username>/RecruitAI.git
- Create a branch for your feature:
git checkout -b feature/your-feature-name
- Make your changes and test in the browser
- Commit with a clear message:
git commit -m "feat: add your feature description" - Push and open a Pull Request:
git push origin feature/your-feature-name
- 🔧 Add support for
.docxresume uploads - 📊 Export screening results as CSV/PDF
- 🧪 Add unit tests for API response handling
- 🌐 Add i18n (internationalization) support
- 📈 Add a score distribution chart
- 🔒 Implement Web Crypto API encryption for stored keys
- API keys are stored in
localStorage(browser-only, never transmitted to third parties) - All API calls go directly from your browser to ScaleDown / Google — no intermediary server
- Resume data is processed client-side and is not stored beyond the browser session
- For shared or public machines, clear site data after use
This project is open-source and available under the MIT License.
Built with ❤️ by haripriyanr
