5 min read

Resume Matcher: Tailor Your Resume to Every Job With AI (GitHub, Scanned)

Tailors your resume and cover letter to each job description, scores the match, exports a PDF.

Resume Matcher logo
✅
Scan: safe. Nothing malicious. One thing to know: the app has no login, and the Docker image serves it on all interfaces, so keep it on your own machine or behind a password if anyone else is on the network. Scanned Sep 29, 2026; the full report is below.

Resume Matcher turns one master resume into a tailored version for each application. Upload your resume as a PDF or Word file, paste a job description, and a model rewrites and reorders your content toward that role, with a match score and highlighted keywords showing what the posting asks for that your resume does not mention. You review each suggestion, rearrange sections by dragging, and export a PDF in one of four templates. It also writes a matching cover letter and can draft interview preparation based on your resume.

It runs on your own machine, with a Python backend and a Next.js front end, and works with Ollama for fully local use or with OpenAI, Anthropic, Gemini, OpenRouter or DeepSeek on your own key. Running it locally means your work history and contact details are not uploaded to a resume website, which is the main reason to choose it over the many hosted tools that do the same job.

Resume Matcher is by Saurabh Rai, Apache-2.0 licensed, and has about 28,500 stars. It is part of Vercel's open-source program, and the interface is available in English, Spanish, Chinese, Japanese and Brazilian Portuguese.

  • Repository: github.com/srbhr/Resume-Matcher
  • Licence: Apache-2.0 (Apache License 2.0)
  • Language: Python. Stars: 28.6K. Forks: 5,062. Last push: Sep 29, 2026.
  • Scan: safe, Sep 29, 2026, commit 9c05e42

Who it is for

Job seekers who apply to many roles and want each resume adjusted to the posting without rewriting it by hand, especially those who would rather not upload personal details to an online resume service.

Getting started

1. Run the published Docker image, then open http://localhost:3000

docker run --name resume-matcher -p 3000:3000 -v resume-data:/app/backend/data ghcr.io/srbhr/resume-matcher:latest

2. Or from source: start the backend (needs Python 3.13+ and uv)

git clone https://github.com/srbhr/Resume-Matcher.git && cd Resume-Matcher/apps/backend && cp .env.example .env && uv sync && uv run app

3. In a second terminal, start the front end (needs Node.js 22+)

cd Resume-Matcher/apps/frontend && npm install && npm run dev

Choose the AI provider in Settings once the app is open. When Resume Matcher runs in Docker and Ollama runs on the host, use http://host.docker.internal:11434 as the Ollama address instead of localhost.

Safety scan

We cloned srbhr/Resume-Matcher at commit 9c05e42 on Sep 29, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secrets, no suspicious patterns, no bare-IP URLs and no committed binaries across 539 files and about 114,000 lines of Python and TypeScript. The hosts are model providers and placeholder test domains; we found no analytics service.
  • No install hooks. docker/start.sh (256 lines) starts the FastAPI backend with uvicorn and the standalone Next.js server inside the container and fetches nothing. Both listen on all interfaces inside the container, and the docker run command publishes port 3000 to your network.
  • The front end's package-lock.json pins 636 packages with 14 advisories (1 critical, 9 high, 3 moderate, 1 low). The critical one is a Next.js remote-code-execution bug in next/og ImageResponse, which Resume Matcher does not use; the highs are mostly brace-expansion denial-of-service bugs in build tooling plus a Tiptap ReDoS in the editor. Updating Next.js would clear the critical regardless.
  • The backend's requirements.txt pins 14 packages with one moderate advisory: LiteLLM 1.86.2, used to reach model providers, has an authenticated SSRF in LiteLLM's proxy server, which this app does not run.
  • One workflow, no pull_request_target, with its six third-party actions pinned to tags rather than commits. Security policy, licence, contributing guide and code of conduct present; no Dependabot or CodeQL.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious codeNone found.
Install-time code2 installer scripts
Committed binariesNone.
CI workflows1 workflow. None use pull_request_target. 6 of 6 third-party actions pinned to a tag rather than a commit.
Network hosts26 distinct hosts referenced from source; most often example.services.ai.azure.com, opencode.ai, local-llm.test, ollama.test. No URLs to bare IP addresses.
Known vulnerabilities15 advisories across 638 pinned packages: 1 critical, 9 high, 4 moderate, 1 low. apps/backend/requirements.txt: 14 packages, 1 advisories; apps/frontend/package-lock.json: 636 packages, 14 advisories.
Project hygieneHas security policy, licence file, contributing guide. Missing automated dependency updates, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Installer scripts (2)
Worst known vulnerabilities (15 of 15)
AdvisorySeverityPackageSummary
GHSA-vcvr-r3jv-pc5jcriticalnext@16.3.3Next.js: Remote Code Execution in next/og ImageResponse
GHSA-j95f-988m-3j2fhigh@tiptap/core@3.29.1Tiptap: Quadratic ReDoS in block and inline Markdown attribute parsing
GHSA-6j4f-fj2g-mc7phighbrace-expansion@5.0.8brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion
GHSA-qhr7-859c-m2p7highbrace-expansion@5.0.8brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion
GHSA-rgw5-rvv9-x895highbrace-expansion@5.0.8brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
GHSA-6j4f-fj2g-mc7phighbrace-expansion@1.1.16brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion
GHSA-mh99-v99m-4gvghighbrace-expansion@1.1.16brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
GHSA-qhr7-859c-m2p7highbrace-expansion@1.1.16brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion
GHSA-rgw5-rvv9-x895highbrace-expansion@1.1.16brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
GHSA-vfj7-8cjw-p6xmhighbraces@3.0.3braces vulnerable to stack-exhaustion denial of service through deeply nested patterns
GHSA-3cv6-jpf6-8222moderatelitellm@1.86.2LiteLLM: Authenticated SSRF and provider-credential exfiltration via unvalidated request-body routing parameters
GHSA-cp6q-959q-f8rhmoderate@tiptap/core@3.29.1Tiptap: mergeAttributes() turns an own __proto__ key into inherited executable DOM attributes
GHSA-q2hr-2g5m-vwhrmoderatebrace-expansion@5.0.8brace-expansion: Quadratic-time expansion of the `{a},b}` rewrite causes CPU denial of service
GHSA-q2hr-2g5m-vwhrmoderatebrace-expansion@1.1.16brace-expansion: Quadratic-time expansion of the `{a},b}` rewrite causes CPU denial of service
GHSA-p98j-92pf-mc4plowdompurify@3.4.13DOMPurify: IN_PLACE: node-removing afterSanitize hook leaves detached subtree event handlers armed, causing DOM XSS

By the numbers

Stars28.6K
Forks5,062
Contributors94
Commits1,654
Open issues19
Open pull requests38
Releases7
Latest releasev1.3.0
LicenceApache-2.0
Main languagePython
Project age6 years
Last pushSep 29, 2026
Tracked files539
Lines of code113.9K
Checkout size57 MB

Lines by language: Python 43K, TypeScript 39.7K, Markdown 21.2K, JSON 8,236, CSS 1,243, Shell 266.

Questions

Is Resume Matcher free?

Yes. It is Apache-2.0 licensed with no paid tier; the project is funded by sponsors and donations. If you use a hosted model, that provider bills your API key for the calls; with a local model through Ollama it costs nothing.

Does Resume Matcher upload my resume?

Not to the project. The app and its data run on your machine, and the resume text goes only to the model provider you select. Choose Ollama and nothing leaves your computer.

Does it help with applicant tracking systems?

It helps with what those systems mostly check, matching the posting's language: keyword highlighting shows which terms are missing and the tailored version works them in. It cannot add experience you do not have, and you should read every suggestion, since a model can overstate what you did.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.