Model or dataset
srbhr/Resume-Matcher avatar
srbhr/Resume-Matcher

Resume-Matcher: a self-hosted AI harness for tailoring resumes per job

The #1 AI Harness for Building Resumes, PDFs, Cover Letters & more, locally with 100+ LLMs support.

28,524 stars5,060 forksPythonApache-2.0

At a glance

What is it?
Resume-Matcher is an Apache-2.0 Python and Next.js application that turns one master resume into a tailored, PDF-ready document for each application, using a local or remote LLM you choose. Here is how it installs, how the pieces fit, and where it stops being the right tool.
Who is it for?
Adopt Resume-Matcher if you already keep a master resume and want a repeatable, self-hosted pipeline that produces a tailored PDF and cover letter per job, with the option of keeping inference on your own machine through Ollama. Skip it if you need a hosted, no-install experience or an ATS score you can defend to a recruiter; the README does not document a scoring formula.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 26, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Resume-Matcher solves, and who it is actually for

The README frames the problem plainly: "Resume Matcher works by creating a master resume that you can use to tailor for each job application." That is the whole pitch. One canonical document, many job-specific variants, generated with an LLM instead of by hand. The intended user is someone applying to enough roles that rewriting bullet points each time has become the bottleneck, and who is comfortable running a local service rather than signing into a SaaS product.

The repository topics list applicant-tracking-system, ats, resume-parser, text-similarity and vector-search, which describes the machinery rather than the marketing. There is also a Next.js frontend and a Python backend, so the project assumes a user who can run a Node build and a Python service, or who can run Docker and skip both. This is not a browser extension and not a hosted web app in the sense of something you sign up for; the README points at resumematcher.fyi for the website, but the workflow it documents is upload, paste, review, export inside your own instance.

The six-step pipeline the README documents

The documented flow is linear and short. Upload a master resume as PDF or DOCX. Paste the job description you are targeting. Review the AI-generated improvements and tailored content. Generate a cover letter and, optionally, interview preparation for that application. Customize layout and sections. Export a PDF with a template you pick.

Two design choices stand out. First, the master resume is the source of truth and the LLM edits around it rather than inventing a document from scratch, which is the safer arrangement if you care about accuracy. Second, the export step is a real rendering concern, not an afterthought: the Dockerfile installs Playwright's system libraries plus fonts-noto-cjk specifically for "Chinese/Japanese/Korean PDF rendering via Playwright". That tells you the PDF path is headless-browser based, and that a slim base image will not do. It also means the image is heavier than a pure Python service would be.

Installing Resume-Matcher with Docker and running a first tailoring pass

The README defers installation to the project site: the "How to Install" link points to resumematcher.fyi/docs/installation, and the repository also carries SETUP.md alongside SETUP.es.md, SETUP.ja.md and SETUP.zh-CN.md. The docker-compose.yml in the repository root is the concrete artifact you can read today, so start there.

The compose file builds from the repository and exposes the app on port 3000 by default, mapping ${PORT:-3000} to 3000 inside the container. Data is persisted in a named volume, so your master resume and generated documents survive a container restart.

yaml
services:
  resume-matcher:
    image: ghcr.io/srbhr/resume-matcher
    build: .
    container_name: resume-matcher
    ports:
      - "${PORT:-3000}:3000"
    volumes:
      - resume-data:/app/backend/data

The environment block is where the LLM gets wired in. The compose file lists the supported providers as openai, anthropic, openrouter, gemini, deepseek and ollama, with openai as the default. If you leave LLM_MODEL empty, the defaults come from apps/backend/app/config.py rather than from the compose file.

bash
LLM_PROVIDER=ollama \
LLM_MODEL=your-model-name \
LLM_API_BASE=http://host.docker.internal:11434 \
docker compose up -d

The commented line in the compose file explains the host address: "For Ollama running on host machine, use host.docker.internal". On Linux, host.docker.internal is not automatically available the way it is on Docker Desktop, so that line is a starting point rather than a guarantee. After the container starts, browse to http://localhost:3000, upload your master resume, and paste a job description. The README's own order of operations is upload, paste, review, cover letter, customize, export.

Where Resume-Matcher is the wrong tool

The project is candid about needing support, and the README carries a donation notice asking users to help continue development. That is not a defect, but it is a signal about how much maintenance capacity sits behind a tool you may come to depend on during a job search.

The harder limitation is scope. Nothing in the README describes an ATS score, a match percentage, or a scanner simulation, despite the ats and applicant-tracking-system topics. If you want a number that tells you how a parser will rank your file, this application does not promise one, and treating an LLM's rewrite as an ATS verdict would be reading something into the project that is not documented. The related searches people run, such as "Is 80% a good ATS score?", are not questions this README answers.

There is also an operational cost. You supply the model, and therefore the quality of every rewrite depends on which provider and model you point it at. A small local model will produce weaker tailoring than a frontier API model, and the project's "100+ LLMs support" claim through LiteLLM does not mean the output is equivalent across them. The compose file even sets LOG_LLM to WARNING by default, so debugging a bad generation means raising that level deliberately.

How it differs from a hosted resume builder

The obvious alternative is a hosted resume tool: a web app where you paste a job description, get suggestions, and download a PDF, with no Docker, no Python, and no API key. The difference is where the data and the model live. In a hosted builder, your resume and the job description travel to someone else's servers and the model is chosen for you. In Resume-Matcher, the compose file lets you point LLM_API_BASE at http://host.docker.internal:11434 and keep inference on your own machine, with the resume stored in the resume-data volume on your own disk.

That trade is real in both directions. Self-hosting buys you control over the model and the data, and costs you an install, a running container, and a provider key or a local model server. A hosted builder costs you that control and buys you zero setup. If you apply to two jobs a month, the hosted route is almost certainly cheaper in time. If you are applying at volume and want the same pipeline every time, running the container locally starts to pay for itself.

Licence, upgrades and what maintenance actually looks like

Resume-Matcher is Apache-2.0, which permits commercial and private use, modification and redistribution, with the usual conditions around preserving notices and stating changes. That is a permissive licence, and it is worth noting that the project accepts sponsorship and displays sponsor logos in the README; sponsorship does not change the licence terms of the code you receive. If you fork it for internal use, the Apache-2.0 obligations travel with your fork. None of this is legal advice, and if you plan to redistribute a modified version, read the LICENSE file in the repository rather than a summary.

Upgrade cost is low but not zero. Releases arrive on a rough cadence: 1.1.0 Voyager in February 2026, 1.2.0 Nightvision in April 2026, and 1.3.0 Crescendolls in September 2026. The repository was last pushed on 2026-09-10 and is not archived, so the codebase is moving. Because the compose file pins only the image tag ghcr.io/srbhr/resume-matcher with no version suffix, pulling again gets you whatever the registry currently serves. If you need reproducibility, pin the image by digest yourself. The data volume is separate from the image, so a container swap should not touch your stored resumes, but the README does not document a migration path for the data directory between major versions.

Editorial conclusion

Adopt Resume-Matcher if you already keep a master resume and want a repeatable, self-hosted pipeline that produces a tailored PDF and cover letter per job, with the option of keeping inference on your own machine through Ollama. Skip it if you need a hosted, no-install experience or an ATS score you can defend to a recruiter; the README does not document a scoring formula. Before committing, verify the current installation steps at resumematcher.fyi/docs/installation, confirm your chosen provider is one of the six listed in docker-compose.yml, and check that ./secrets/llm_api_key or LLM_API_KEY is set the way your deployment expects.

Frequently asked questions

How do I install Resume-Matcher?

The README links to resumematcher.fyi/docs/installation for installation instructions, and the repository also includes SETUP.md. The repository root contains a docker-compose.yml that builds the app and exposes it on port 3000 by default. You then set LLM_PROVIDER and either LLM_API_KEY or LLM_API_BASE before starting the container.

How do I use Resume-Matcher?

The README describes six steps: upload your master resume as PDF or DOCX, paste a job description, review the AI-generated improvements, generate a cover letter and optional interview preparation, customize the layout, then export a PDF. The workflow is built around maintaining one master resume and tailoring it per application.

Which LLM providers does Resume-Matcher support?

The docker-compose.yml lists openai, anthropic, openrouter, gemini, deepseek and ollama as supported providers, with openai as the default. The README also names Claude, ChatGPT, DeepSeek, Kimi, GLM and Gemma, and states that both local and remote LLMs are supported.

Can Resume-Matcher run fully locally without sending my resume to an API?

Yes, if you point it at a local model server. The compose file includes a commented example using LLM_API_BASE=http://host.docker.internal:11434 for Ollama running on the host machine. In that configuration the model runs on your hardware and the resume data stays in the resume-data volume.

Does Resume-Matcher give an ATS score?

The README does not document an ATS score or match percentage. Its documented output is tailored resume content, a cover letter, optional interview preparation, and a PDF export. Repository topics include ats and applicant-tracking-system, but no scoring formula is described in the README.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. srbhr/Resume-Matcher on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/srbhr-resume-matcher.svg)](https://hysenlabs.com/projects/srbhr-resume-matcher)