Open source ATS: the options, and how to add resume parsing
Published
An open source ATS gives you an applicant tracking system you can host, read and change yourself, with no per-seat fee. The three projects most teams end up comparing are OpenCATS (a dedicated recruiting ATS in PHP), the Recruitment app in Odoo's open source Community edition, and the recruitment module in Frappe HR. Each tracks jobs, candidates and pipeline stages well. What none of them gives you out of the box is reliable structured data from an uploaded CV: the name, contact details, work history and skills as fields rather than an attached file. This guide compares the three, then shows how to close that gap.
We build ResumeJSON, a CV parsing API, so read the parsing section as written by an interested party. The comparison of the ATS projects applies whatever you parse with, and for some teams the answer is to parse nothing at all.
What "open source ATS" should mean before you pick one
The phrase covers three different things, and the difference decides your maintenance bill:
- A dedicated ATS. A project whose whole purpose is recruiting: jobs, candidates, submissions, pipeline. OpenCATS is this.
- An ATS module inside a suite. Recruiting as one app in a wider ERP or HR system. Odoo and Frappe HR are this. You get employees, payroll and time off on the same database, and you also run the whole suite.
- A codebase you start from. Your own app with an ATS data model. If that is where you are heading, How to build an ATS walks the tables and the pipeline.
Then check the licence. "Open source" ranges from weak copyleft to strong copyleft, and it matters the moment you modify the code and offer it to anyone outside your company.
Open source ATS options compared
All figures below were read from each project's own pages and repository as of October 2026.
| OpenCATS | Odoo Recruitment (Community) | Frappe HR | |
|---|---|---|---|
| What it is | Dedicated ATS and recruiting CRM | Recruitment app in an ERP suite | Recruitment module in an HR and payroll suite |
| Language | PHP | Python | Python |
| Licence | MPL 2.0, older code under CATS Public License 1.1a | LGPLv3 | GPLv3 |
| Latest release | v0.11.1, September 2026 | Ongoing suite releases | Ongoing suite releases |
| Best for | Staffing agencies and recruiting teams | Companies already on, or moving to, Odoo | Companies wanting HR and payroll beside hiring |
| Structured CV fields out of the box | No; the old import service ships disabled | Applicant details from the online form | Applicant details from the job application form |
OpenCATS
OpenCATS describes itself on its home page as:
a free, community-maintained applicant tracking system and recruiting CRM for teams that need a practical way to manage candidates, jobs, submissions, and hiring activity without vendor lock-in.
It is the most focused of the three. Candidates, jobs, companies, contacts and submissions are first-class records, and the model fits a staffing agency placing people at client companies. The repository shows active work as of October 2026, with a public roadmap that names PHP 8.4 and 8.5 fixes alongside larger API and integration features, and the README asks contributors to read CONTRIBUTING.md first.
The resume side is where it shows its age. The default config.php in the repository carries this line:
/* Resfly.com Resume Import Services Enabled */
define('PARSING_ENABLED', false);Below it are paths to antiword, pdftotext, html2text and unrtf. Those tools turn an uploaded document into text so it can be searched. They do not turn it into fields. A recruiter still types the candidate's name, phone and job history into the record, or relies on keyword search across the extracted text.
Odoo Recruitment (Community edition)
Odoo is a full business suite published under LGPLv3. Its recruitment page describes a pipeline where you "click and drag an applicant card to quickly change where they are in the pipeline," plus stage-based automated emails and online interview scheduling. The hosted Odoo Online offers one app free "with unlimited users," per the same page; the paid tiers on odoo.com are per user per month and cover all apps.
Odoo's page says that "when applicants apply online, their info is indexed and added to their application automatically." Read that as the fields the applicant typed into the careers form, attached to the applicant card along with their documents. If your candidates arrive through your own website form, that covers a lot. If they arrive as a folder of PDFs, an email inbox or an old database export, you still need something to read the CV.
Frappe HR
Frappe HR is an open source HR and payroll system on the Frappe framework, licensed GPLv3, with job openings and job applicants in its recruitment module. Its site pitches it as covering everything "from recruitment to exits." It suits a company that wants hiring, onboarding, attendance and payroll in one place and has, or wants, Python developers. Like Odoo, it is a suite first, so the recruitment screens are one part of a larger system you operate.
The gap all three share: CVs as files, not fields
Every ATS above stores the CV. None of them, in its default open source form, reliably turns that CV into structured fields you can filter on: years of experience, last employer, each job's dates, a skills list. That matters for three jobs:
- Search and filtering. "Python developers with five or more years, currently in Berlin" needs fields. Keyword search over extracted text finds every CV that mentions Python once.
- Data entry. A recruiter retyping a CV into a candidate record is where most of the time goes in a self-hosted setup.
- Imports. Moving thousands of old CVs into a new ATS is impossible by hand. Bulk resume parsing covers running a backlog like that.
You have two honest choices: parse inside the ATS's own stack, or call a parsing service from a small hook.
How to add resume parsing to a self-hosted ATS
The pattern is the same whichever ATS you run. A file arrives, you send it to a parser, and you write the returned fields onto the candidate record.
- Find the hook. In Odoo and Frappe HR, a server-side automation or a small custom module fires when an applicant record is created with an attachment. In OpenCATS, the upload handling in its PHP modules is where a call fits, or you run a separate job that watches the attachments table.
- Send the file to a parser. With ResumeJSON, that is one multipart request:
curl -X POST 'https://resumejson-resume-cv-parser-api.p.rapidapi.com/v1/parse' \
-H 'x-rapidapi-key: YOUR_KEY' \
-H 'x-rapidapi-host: resumejson-resume-cv-parser-api.p.rapidapi.com' \
-F 'file=@cv.pdf'- Map the response onto your fields. The response carries a
resumeobject withbasics(name, email, phone, location), aworkarray, aneducationarray,skills,certifications,languagesandtotal_years_experience. Dates come back asYYYY-MM,YYYYornull, and a field the CV does not state isnull. The field reference lists every field. - Keep the original file. Store the parsed JSON beside the CV, never instead of it. A recruiter should always be able to open what the candidate actually sent.
- Show the parsed values for review. Prefill the candidate form and let a person confirm it. Parsing removes the typing, and a human still owns the record.
For a Python suite, the call from a server action is a few lines of requests; Python resume parser has the full example. For OpenCATS, Resume parser PHP shows the same call with cURL in PHP. You can try a CV on the free parser first to see what comes back before you wire anything.
Or keep it all self-hosted
If no candidate data may leave your servers, an external API is the wrong answer, whatever its quality. Then the open source parsers are the route: Open source resume parser compares what exists and where each one breaks. Expect to spend real time on layouts, two-column PDFs and scans, which is the work a hosted parser exists to absorb.
Which open source ATS to choose
- Choose OpenCATS if you are a recruiting team or agency, want a dedicated tool, and are comfortable running a self-hosted PHP application. Plan to add parsing yourself.
- Choose Odoo Recruitment if your company already runs Odoo, or wants accounting, sales and HR on one system.
- Choose Frappe HR if hiring sits inside a wider HR process with payroll and attendance, and your team works in Python.
- Build your own if the ATS is part of a product you sell, such as a job board or a staffing platform. A suite's data model will fight your product's.
When you do not need parsing at all
Parsing earns its place with volume or with imports. Skip it when:
- You hire a handful of people a year. Typing ten candidate records is faster than wiring and maintaining a hook.
- Every applicant fills in your form. If the careers page already asks for name, email, phone and current role, the form gives you the fields that matter most, and the CV is a reference document.
- Your search needs are simple. If recruiters read every CV anyway, keyword search over extracted text, which OpenCATS already does, may be enough.
Add parsing when retyping becomes the bottleneck, or when you are about to import a backlog. Before then, an open source ATS on its own is a perfectly good tool.