Skip to content

Repository files navigation

AI CV-to-Job Match Analyzer

Upload a CV (PDF) and a job description (URL or pasted text) and get an ATS-style match score out of 100, with evidence-based feedback: which requirements are met, which are missing, and concrete suggestions for improving the CV.

The match score is computed deterministically in TypeScript from a fixed, weighted rubric — not by the LLM — so results stay consistent regardless of which model runs the analysis. The LLM is only used to extract structured data from the CV/job text, classify each requirement against the CV with evidence, and write the final natural-language explanation.

Runs entirely locally: no accounts, no database, nothing persisted server-side.

How it works

CV PDF ──► text + layout extraction ──► LLM structured extraction ──► CandidateProfile
                                                                              \
                                                                               ► matching + scoring ──► score/100 ──► LLM explanation
                                                                              /
Job URL/paste ──► text extraction ──► LLM structured extraction ──► JobProfile

Scoring weights (fixed, sum to 100):

Category Weight
Required technical skills 35
Relevant experience 20
Responsibilities / role intent 15
Preferred technologies 10
Seniority alignment 5
Soft skills 5
ATS structure / parseability 10

Every requirement is classified as exact, semantic, partial, or missing, each backed by evidence quoted or closely paraphrased from the actual CV — the tool is explicitly constrained to never suggest claiming a skill or experience that isn't there.

Tech stack

  • Frontend/backend: Next.js (App Router) + TypeScript, Tailwind CSS, shadcn/ui, Next.js Route Handlers (no separate backend)
  • AI orchestration: LangChain.js, giving a shared interface across providers
  • Model providers: Groq (hosted) and Ollama (local) — pick whichever's configured at runtime
  • Validation: Zod schemas for every structured LLM output (CV/job profiles, requirement matches, ATS layout analysis, final result)
  • PDF parsing: pdfjs-dist, for both text extraction and layout/structure signals (columns, sidebars, tables, non-standard headings) that feed the ATS parseability score
  • Job URL extraction: fetch + Cheerio; falls back to prompting for pasted text if a URL can't be parsed
  • Tests: Vitest

Getting started

1. Install dependencies

npm install

2. Configure at least one model provider

Copy the example env file:

cp .env.example .env.local

Then set up at least one of:

  • Groq (hosted, fast) — get an API key from console.groq.com/keys and set GROQ_API_KEY in .env.local.

  • Ollama (local, private, free) — install Ollama, pull a model, and make sure it's running:

    ollama pull llama3.1
    ollama serve

    OLLAMA_BASE_URL defaults to http://localhost:11434 if unset.

The app only offers providers that are actually configured/reachable — check GET /api/providers to see what's currently available.

3. Run the dev server

npm run dev

Open http://localhost:3000, upload a CV PDF, provide a job description (URL or paste), pick a provider, and run the analysis.

Testing

npm run test        # run once
npm run test:watch  # watch mode

Security notes

This app is designed to run locally only. The job-URL fetcher blocks requests to private/internal network addresses (SSRF protection) and CV uploads are capped at 10MB, but there is currently no authentication or rate limiting on any endpoint. If you deploy this publicly, add a rate limiter in front of the API routes first — otherwise anyone with the URL can consume your configured provider's API quota.

Project structure

app/
  page.tsx              # main upload/input UI
  results/page.tsx       # results view
  api/cv/extract/        # PDF -> CandidateProfile
  api/job/extract/       # URL/paste -> JobProfile
  api/analyze/            # matching + scoring + explanation orchestration
lib/
  pdf/                    # text + layout extraction (pdfjs-dist)
  job/                    # job URL fetching (Cheerio)
  llm/                    # LangChain provider abstraction + structured-output extraction
  scoring/                # deterministic scoring engine (no LLM)
  schemas/                # Zod schemas for every structured type
components/
  ui/                     # shadcn/ui primitives
  ResultsView/            # score breakdown, match list, ATS review, recommendations
tasks/
  prd-*.md                # product requirements doc
  tasks-*.md              # implementation task list

About

AI-powered CV-to-job match analyzer — upload a CV and job description, get a deterministic 0–100 ATS-style match score with evidence-based feedback.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages