# Resume Matcher Features

> Everything Resume Matcher does, in the order you use it: paste a job description, review every change the AI proposes, polish the resume in the builder, write the cover letter, and track the application. Free and open source (Apache-2.0), self-hosted, with the AI model you choose.

- **URL**: https://resumematcher.fyi/features/
- **GitHub**: https://github.com/srbhr/Resume-Matcher
- **Docs**: https://resumematcher.fyi/docs/

The screenshots on the page use a demo profile: "Sarah Chen" and every company shown are fictional.

## How it fits together

1. **Connect an AI model** in Settings: a cloud provider with your own API key, or a local model.
2. **Add a master resume**: upload a PDF or Word file, or build one with the Resume Wizard.
3. **Paste a job description** on the Tailor page. The AI proposes targeted edits to your master resume.
4. **Review the changes** in a before-and-after preview, then confirm or regenerate.
5. **Polish** the tailored resume in the builder: pick a template, adjust the layout, edit anything.
6. **Generate extras** for the same job: cover letter, outreach message and interview prep.
7. **Download** the resume and cover letter as PDFs.
8. **Track** the application on a Kanban board. Confirming a tailored resume adds its card for you.

Your master resume is never overwritten. Each tailored version is saved as its own resume, linked to the master it came from and the job it was written for.

## Tailor

Tailoring rewords what's already in your resume. It doesn't invent experience, and nothing is saved until you've reviewed the changes.

### Start from a master resume

- Upload a PDF, DOC or DOCX file up to 4 MB. The AI turns it into structured sections you can edit; a copy of the original text is kept. Scanned, image-only PDFs have no text layer and are rejected (run them through OCR first).
- No resume file? The Resume Wizard asks one question at a time (at most 15) and builds the resume in a live draft. It's instructed never to invent employers, titles, dates, degrees, certifications, metrics, tools or skills.
- Keep up to five master resumes as career tracks (for example backend and ML). Exactly one is the default; the Tailor page starts from it.

### Paste the job description

Paste the posting (up to 100,000 characters), pick a tailoring intensity and click Generate Tailored Resume:

- **Light nudge**: minimal edits to better align your existing experience.
- **Keyword enhance** (default): blends in relevant keywords without changing role or scope.
- **Full tailor**: comprehensive tailoring using the job description.

### What happens behind the button

1. **Job analysis.** The AI extracts the company, role, required and preferred skills, key responsibilities and keywords. They're saved with the job, so the tracker card gets its company and role without another AI call.
2. **Bullet selection.** The AI scores each bullet point for relevance. It only scores; it can't rewrite or invent bullets. Code keeps up to three bullets per job or project and checks, by rendering the page, that the resume fits on one page.
3. **Skill plan.** The AI proposes which skills to emphasise. Code accepts a skill only if it's already in your resume, appears in your resume's text, or is a required or preferred skill that appears word for word in the job description.
4. **Targeted edits.** The AI returns a list of specific edits, each quoting the original text it replaces. Code verifies every quote against your resume and rejects edits aimed at protected fields.
5. **Safety nets and polish.** Code restores your personal details and dates, keeps every original skill, removes overused "AI-sounding" phrases (unless the job description uses them), and reverts any rewritten line that introduces a number your original doesn't contain.

The whole run has a time limit (four minutes by default) so a slow model can't hang the app.

### Review before anything is saved

- A change summary: skills added and removed, certifications added, descriptions modified, and high-risk changes.
- What bullet selection did, for example "Kept 9 of 11 bullets (up to 3 per job or project) · fits on one page".
- A high-risk warning when the AI added something, usually a skill taken from the job description, so you can confirm it's true for you.
- Before-and-after diffs for the summary, skills and each changed bullet.

**Confirm & Save** keeps the result; **Reject & Regenerate** discards it and tries again. The decision covers the whole preview. Guardrails stop invented numbers, employers and dates, but wording can still overstate your role: you are the final check.

When you confirm, the tailored resume is saved as a new resume titled "Role @ Company", linked to its master and its job; its card lands in the Applied column of the tracker; and, if switched on in Settings, a cover letter, outreach message and interview prep are generated with it.

While the preview is open, an ATS Score Breakdown card shows a weighted heuristic: 55% keyword match, 25% coverage of the job's required and preferred skills, 20% section completeness. It isn't a simulation of any real applicant tracking system, and it isn't saved.

## What the AI can and can't change

Enforced in code, not just requested in the prompt.

**The AI can:**

- Reword your summary and bullet points using the job's language
- Reorder and emphasise skills
- Choose which bullets to keep (up to three per entry)
- Add a skill the job requires, if it appears word for word in the job description (flagged as high risk)

**The AI can't:**

- Change your name, email, phone, location or links
- Change employers, job titles or dates
- Change schools, degrees or education dates
- Add a number, percentage or metric that isn't in your original
- Remove your existing skills, certifications, languages or awards
- Add new jobs, schools or projects
- Touch your custom sections

## Build

Every resume, master or tailored, opens in the builder: an editor on the left and a live, paginated preview on the right.

- Edit every section in place: personal info, summary, experience, education, projects, and skills and awards.
- Format bullet text with bold, italic, underline and links; toggle the bullet marker per line.
- Add, duplicate or remove jobs, schools, projects and bullet points. Rename, hide, show and reorder sections (move up/down or drag and drop).
- Custom sections of three kinds: free text, a list of items (like a job entry), or a simple list of strings.
- Preview tools: zoom, a margin overlay and a live page count; tabs for Resume, Cover Letter, Outreach Mail, Interview Prep and, on tailored resumes, JD Match.
- Actions: AI Regenerate, Reset (to the last saved version), Save (it also autosaves), Download (PDF with your current template settings).

### Seven templates

| Template | Layout | Accent colour |
|---|---|---|
| Single Column | 1 column | No |
| Two Column | 2 columns | No |
| Modern | 1 column | Yes |
| Modern Two Column | 2 columns | Yes |
| LaTeX | 1 column | No |
| Clean | 1 column | No |
| Vivid | 2 columns | Yes |

Formatting: A4 or US Letter; margins 5–25 mm on each side (default 10 mm); section, item and line spacing in five steps; base font size plus the scale of your name and section headers; serif, sans-serif or monospace fonts, chosen separately for headers and body; compact mode and contact icons on or off; accent colour (blue, green, orange or red) on Modern, Modern Two Column and Vivid; reset to defaults at any time.

Two-column templates keep the main content first in the reading order, so text extractors read your experience before the sidebar.

### JD Match

On a tailored resume, the JD Match tab puts the job description next to your resume and highlights, in yellow, every job-description keyword your resume already contains. The match rate is plain arithmetic, with no AI involved:

1. Take the words in the job description, drop common English words and job-posting filler (such as "team", "role" and "experience"), and keep words of three or more letters.
2. Do the same for your resume.
3. Match rate = job-description keywords found in your resume ÷ all job-description keywords.

Green at 50% or more, amber from 30%, red below 30%. Because it counts every meaningful word in the posting, including company background, a strong resume often lands in the 30–50% range. Use it to spot missing skills and terms, not as a pass mark. It currently counts plain a–z words only, so accented words and Chinese, Japanese or Korean text aren't counted.

## Write

Generated from your resume for the same job, on demand from the builder or automatically when you confirm a tailored resume (Settings → Content Generation).

- **Cover letter**: 100–150 words, written from your resume for the specific job; the prompt tells the model not to invent anything that isn't in your resume. Edit it beside the print layout, then save, regenerate or download it as a PDF.
- **Outreach message**: a 70–100 word cold email or LinkedIn message. Edit, regenerate, copy to the clipboard.
- **Interview prep**: role-fit analysis (matches and gaps), resume-based questions with a focus area and suggested answer points, project follow-ups, skill gaps (preparation targets, not skills added to your resume) and talking points.

The cover letter and outreach prompts can be replaced with your own in Settings.

**AI enrichment (master resume).** Click Enhance Resume on your master resume. The AI looks for thin experience and project entries and asks up to six questions about them. From your answers it writes two to four new bullet points per item, which you review before clicking Add to Resume. It only uses details you provide; it doesn't invent metrics.

**AI Regenerate (any resume).** In the builder, choose the experience entries, projects or skills to rework and write an instruction such as "use stronger action verbs". You get a before-and-after preview before anything is applied. The prompt forbids new facts, metrics, dates, companies, titles or accomplishments.

## Track

The Application Tracker is a Kanban board for your job search. Every tailored resume you confirm gets a card automatically, and you can add cards by hand for jobs you haven't tailored for yet.

- **Seven stages**: Saved, Applied, No Response, Response, Interview, Accepted and Rejected.
- **Cards** show the company, the role, the date you applied, and a Shared resume badge when the same master resume backs more than one application. The date is stamped when a card is created in any stage other than Saved, or when it first moves out of Saved.
- **Working the board**: drag and drop cards; scroll with the arrow buttons or jump to a stage with the chips; select several cards to move them with Move to… or delete them; Manage hides stages you don't use (at least one stays visible).
- **Card details**: the full job description, your notes, and the exact resume you applied with (Edit Resume opens it in the builder). If that resume has since been deleted, the card still opens and tells you.
- **Add an application by hand**: choose a resume, paste the job description and pick a starting stage, such as Saved. Company and role are optional; leave them blank and the AI extracts them from the job description.

## Run it your way

Resume Matcher doesn't include an AI model. You connect one, and the app handles the prompts, checks and formatting.

| Provider | Default model in Settings | Runs |
|---|---|---|
| OpenAI | `gpt-5-nano-2025-08-07` | Cloud |
| Anthropic (Claude) | `claude-haiku-4-5-20251001` | Cloud |
| Google Gemini | `gemini-3-flash-preview` | Cloud |
| DeepSeek | `deepseek-chat` | Cloud |
| OpenRouter | `deepseek/deepseek-chat` | Cloud |
| Groq | `llama-3.3-70b-versatile` | Cloud |
| Azure AI Foundry | `mistral-large-latest` | Cloud |
| Ollama | `gemma3:4b` | Your machine |
| OpenAI-compatible server (llama.cpp, vLLM, LM Studio) | you type it | Your machine |

You can type any model name your provider offers. There's no official minimum model, but small models can struggle with the structured edit format the tailoring step uses.

Configure it in Settings (provider, model, API key, optional base URL; Save, then Test Connection) or with `LLM_PROVIDER`, `LLM_MODEL`, `LLM_API_KEY` and `LLM_API_BASE` in `apps/backend/.env` or your Docker environment. Provider names are lowercase (`anthropic`, `ollama`). Settings saved in the app take precedence.

Settings also has: system status (LLM health, database connection, counts of resumes, jobs and tailoring runs, master resume configured); reasoning effort for reasoning-capable models (gpt-5 family, Claude 3.7+, DeepSeek R1, OpenAI o1/o3; Auto sends nothing); content generation switches (all off by default; custom cover letter and outreach prompts must keep the `{job_description}`, `{resume_data}` and `{output_language}` placeholders); the default tailoring intensity; UI and content language; and a danger zone (Clear API keys, Reset database; neither can be undone). API keys are stored encrypted, one per provider.

### Languages

English, Spanish, Chinese (Simplified), Japanese, Brazilian Portuguese, French and Korean. The UI language and the content language (what the AI writes in) are set separately. PDFs include Noto Sans fonts for Chinese, Japanese and Korean text.

### PDF export

A headless Chromium prints a print-only version of your resume, so the PDF contains real, selectable text and real headings, two-column layouts keep the main content first in the reading order, and the page matches the builder. Export needs the frontend running; locally, run `uv run playwright install chromium` or have Chrome or Edge installed. The Docker image includes everything.

### Your data and privacy

Everything lives in `apps/backend/data/` or the Docker volume: `resume_matcher.db` (SQLite: resumes, job descriptions, tailored versions, tracker board), `config.json` (non-secret settings), and API keys encrypted at rest with a secret key file readable only by your user account.

Only the AI requests you trigger leave your machine, sent to the provider you chose; with a cloud provider that includes your resume (with your contact details) and the job description. The app contains no analytics or tracking code. At startup, LiteLLM fetches a public model price list; that request carries none of your data. With Ollama or another local model server, everything stays on your computer.

### Install

```bash
docker run --name resume-matcher -p 3000:3000 \
  -v resume-data:/app/backend/data \
  srbhr/resume-matcher:latest
```

Then open http://localhost:3000/settings to connect a model. The image is on Docker Hub (Docker-Sponsored Open Source) and GitHub Container Registry (`ghcr.io/srbhr/resume-matcher`), built for `linux/amd64` and `linux/arm64`. To run from source you need Python 3.13+, Node.js 22+, npm and uv.

- [Docker install guide](https://resumematcher.fyi/docs/docker-installation/)
- [Install without Docker](https://resumematcher.fyi/docs/installation/)
- [Fully local with Ollama](https://resumematcher.fyi/docs/docker-ollama/)

## What it doesn't do

- **It isn't a hosted website.** You run it yourself, locally or in Docker. It's built for one user.
- **It doesn't apply for jobs** or connect to job boards or employers' systems. The tracker is your own record.
- **It isn't an ATS checker.** Its scores are keyword and section heuristics, not predictions of how any employer's software will rank you.
- **It doesn't write a resume from nothing.** It works from your uploaded resume or your answers in the wizard.
- **It doesn't read scanned PDFs.** Files need a text layer.
- **It exports PDF only.** Word files are accepted as input, not output.
