Methodology

What the scoring, matching and parsing actually do, in the same terms as the source code — not a marketing summary of it. Every rule below runs in your browser, on your device, and produces the same result every time for the same input.

Direct answer

The ATS Resume Checker scores a resume against 56 distinct, deterministic rule checks — plain conditional logic written in TypeScript, not a trained model — grouped into six weighted categories that sum to 100 points. The Job Description Matcher compares a resume against a job posting using a hand-built skill taxonomy of 317 canonical skills across 16 domains, with 139 alternate spellings mapped onto 67 of those skills (456 total recognized terms), so “K8s” and “Kubernetes” are treated as the same skill. Nothing here is generated by an AI model. Nothing leaves your browser to compute any of it.

1. ATS Resume Checker

Six categories, each starting at full marks and losing points only for rules that actually fire. A rule can never deduct more than half its own category’s maximum — so one repeated issue in a long, otherwise strong resume cannot zero out that category the way a single catastrophic rule would in a simpler scoring model.

CategoryPointsWhat it judges
Contact & Identity15Name, email, phone, location, LinkedIn presence
Sections & Structure20Section presence, heading safety, section order, entry completeness
ATS-Safe Formatting20Icons, risky glyphs, emoji, tabs, HTML, font choice, margins, date-format consistency
Content Quality25Weak verbs, first-person pronouns, quantification, bullet length, summary length
Keywords & Skills10Skill count, grouping, presence of your target role in the document
Length & Density10Page-count estimate against career stage, bullets per role

A category cannot score points for content that does not exist — an empty Skills section caps the Keywords category at 0, regardless of anything else on the page. This was added after an early version of the engine gave a completely empty resume a passing score, purely because there was nothing present to format badly. That evidence gate is why an empty resume now reliably fails: it is directly asserted by an automated test (src/engine/engine.test.ts) that always returns a failing grade with critical-severity issues for a blank document, and a separate test that keeps the bundled sample resume — which deliberately contains a few weak bullets — in the A-to-C range rather than a perfect score.

One rule people find genuinely surprising: mixing date formats (“Mar 2022” alongside “03/2022” on the same resume) causes the inconsistent entries to be read as undated by many parsers, which can mean zero months of tenure credited for that role. The checker flags this specifically, rather than lumping it in with generic formatting advice.

2. Job Description Matcher

The match score blends three signals: skills matched against the taxonomy (60% of the score), other repeated domain terms outside that taxonomy such as industry-specific nouns (30%), and whether the job title appears in your resume (10%). If a posting contains no skills the taxonomy recognizes, that component is removed from the score entirely and the remaining signals are rescaled — a nurse’s resume scored against a Kubernetes-heavy posting reads as 0% match, not a misleading partial score inflated by the absence of unrelated terms.

Skills mentioned inside a posting’s “Requirements” or “Qualifications” section are weighted 1.5× over the same skill mentioned in general boilerplate, and repeated mentions add further weight, capped so that stuffing a posting with one keyword cannot dominate the score. Alias matching runs as a longest-match sweep, so a two-word phrase like “machine learning” is recognized as one skill and never double-counted as the separate word “learning.”

3. Resume Bullet Improver

Detects 28 distinct weak-verb and filler-phrase patterns (“responsible for,” “worked on,” “helped,” and 25 others), 30 buzzword or cliché phrases (“synergy,” “results-driven,” “team player”), passive voice, missing quantification, and nine first-person pronoun forms. Suggested replacement verbs are drawn from a set of 117 strong action verbs across eight impact categories (built & engineered, led & owned, automated & scaled, and five others), so a suggestion for “managed” offers other leadership verbs rather than a random thesaurus swap.

The rewrite pipeline is deliberately mechanical and fixed-order: strip a leading pronoun, swap the weak opener, remove filler, force past tense, tidy punctuation. It never invents a number, a technology or a claim of ownership the original bullet did not make. Where a fix genuinely needs a fact only you have — a missing metric, a missing outcome — it is offered as a template with blanks, never a filled-in guess.

4. Resume parsing and PDF text extraction

PDF import uses pdf.js, running entirely in your browser, and reconstructs reading order geometrically — by the actual x/y position of each piece of text on the page — rather than trusting the order text happens to be stored in the file, because in a two-column resume that stored order is frequently wrong. A horizontal gap wider than 60 points between two pieces of text is treated as a column boundary rather than a space. A page with fewer than roughly 120 extractable characters is flagged as likely a scanned image rather than real text, because a genuine text-based resume runs to thousands of characters — under that threshold there is nothing for any ATS to index no matter how the rest of the tool scores it.

This parser is explicitly heuristic, and says so in its own source comments: it will sometimes mis-assign a line on an unusual layout, in the same way a real applicant tracking system’s parser does. That fallibility is treated as informative rather than hidden — a field the import review screen shows as missing is a field a real employer’s system is plausibly missing too.

5. Length, completeness and duplicate detection

Page-length is estimated analytically from font size, line height, margins and per-font average character width, rather than measured from a rendered DOM element — the same estimate has to be available in a build-time test, during static-site generation, and in the browser, and only a formula works in all three places.

The completeness checklist re-weights the same twelve items by career stage: a Projects section is worth more to someone with no work history yet and less to someone with eight years of it, using experience-years computed from merged, non-overlapping date ranges so two concurrent jobs are not double-counted as double the tenure.

Duplicate-content detection flags near-identical bullets using a similarity threshold of 0.6 (word-overlap based) — chosen so that two different bullets that merely share a technology name are not falsely flagged, while a copy-pasted-and-lightly-edited bullet still is.

Browser-side processing and privacy architecture

Every calculation on this page runs as ordinary JavaScript in your browser. The only place anything you type is sent is the contact form, and only when you fill it in and press Send. Nothing about your resume, a pasted job description, or anything you type into any tool is ever part of that request or any other. The analytics and advertising scripts that load on every page are listed, with what each one can and cannot see, on the privacy page.

How to verify this yourself

  1. Open your browser’s developer tools and select the Network tab.
  2. Use the ATS Checker, the Job Matcher, and the Builder — import a resume, paste a job description, edit a bullet.
  3. Confirm the only requests are for this site’s own files, plus the third-party scripts listed on the privacy page. None of them carry resume or job-description text.

What ATSResumeKit does not check

  • Whether the facts in your resume are true — the engine checks form, not honesty.
  • Grammar or spelling. Formatting and keyword rules are enforced; prose quality is not proofread.
  • A specific named vendor's exact parser (Workday, Greenhouse, Lever, iCIMS and others all differ). The rules follow widely-documented parsing conventions, not one company's implementation.
  • Whether you will get an interview. That depends on the employer, the market and the rest of the applicant pool — none of which any offline tool can see.

What a score does and does not promise is set out in the disclaimer.

Evidence and what is and isn’t independently benchmarked

The claims above are backed by the automated test suite that runs on every change to this codebase, not by a separate research study:

  • src/engine/engine.test.ts asserts an empty resume always receives a failing grade with critical-severity issues, and that the bundled sample resume consistently lands in the passing A-to-C range.
  • src/export/pdf.test.ts asserts every exported PDF embeds real, extractable text rather than a rasterized image, across every template and both supported page sizes.
  • src/lib/resumeParser.test.ts covers the parsing heuristics described above against a range of sample layouts.

What this page will not claim, because the repository contains no evidence for it:

  • No claim of accuracy against any specific named commercial ATS (Workday, Greenhouse, Lever, Taleo, iCIMS and others all parse differently, and none of them has been individually tested against this tool). The heading and formatting rules follow widely documented parsing conventions common across these systems, not a benchmark against any one of them.
  • The page-length estimate’s stated accuracy (“about 4%”) is an internal design estimate made while building the formula, not the result of an external accuracy study.
  • The 0.6 duplicate-detection threshold was chosen by testing against example bullet pairs during development, not a published benchmark dataset.

Where evidence does not exist, this page says so rather than rounding up. If you find a rule that is wrong, missing, or produces a bad recommendation for your profession, the contact page reaches the person who can change it.

How rules are maintained

Every rule is deterministic and hand-written directly in the engine’s TypeScript source. There is no separate rules database, no A/B-tested variant, and no model that retrains — a rule changes only when someone edits the code and that change ships in a release, the same way any other part of the product changes. See the About page for how to suggest a change.

Controlled parsing experiments

Three controlled comparisons against this codebase’s own pipeline — the same pdf.js text extraction and the same parser and scorer described above — each changing exactly one variable and holding the rest of the content identical. Run 2026-09-19, reproducible with npm run experiments; the fixtures, generator and comparison code are in src/experiments/ in the repository. See the evidence hub for these same three results in one consistent, comparable format, plus which further experiments are planned but not yet run.

One column vs. two columns

Control: the real exporter, one column. Variant: an equivalent two-column layout — not producible by this product’s own builder, since it deliberately never generates a multi-column PDF (see above), so this variant was built separately for the test only, using the same fonts and text-wrapping code as the real exporter. In this experiment, the two-column variant’s extracted text merged the “Professional Summary” heading onto the same line as an unrelated contact detail from the neighboring column, and the parser then failed to recognize that heading as a section at all: it detected 6 of 7 sections instead of 7, and the number of lines it could not assign to any section rose from 2 to 6. This result does not establish behavior across other ATS products.

Contact icons on vs. off

Control: the icon setting off. Variant: identical resume with it turned on, generated through the real exporter. The two resulting PDF files were extracted with the same pdf.js pipeline used above, and the extracted text is identical — this setting does not currently change what a parser reads from the exported PDF at all. (The raw PDF files themselves are not byte-identical: pdf-lib embeds the current time in each file’s generation-date metadata on every export, so two exports made a moment apart differ in that metadata regardless of content. That metadata sits outside the text a parser reads, so it does not affect this result — but it is why extracted text, not raw file bytes, is the comparison reported here.) There is therefore no PDF-extraction difference to report for this variable: what changed is this site’s own ATS Resume Checker score, not anything a PDF parser would see. In this experiment, turning icons on dropped the formatting category from 20 to 17 points and added one additional flagged rule in that scoring tool — a statement about this checker’s own scoring logic, not about PDF parsing or about any external ATS.

Standard vs. unconventional heading vocabulary

This tests a vocabulary substitution across four headings at once, not one heading in isolation — the result below cannot be attributed to any single renamed heading on its own. Control: this page’s own default headings (Professional Summary, Skills, Work Experience, Education). Variant: identical content with all four of those headings replaced simultaneously by phrases this codebase already recognizes as needing a suggested correction (“My Journey,” “Toolbox,” “School Days,” “Why Me”). In this experiment, the number of sections the parser could map dropped from 7 to 3, and its count of unassigned lines rose from 2 to 27 — every line under one of the four renamed headings, including the bullets beneath it, went unassigned rather than merely mis-labeled.

Limitations, for all three: these measure this codebase’s own pipeline only, not Workday, Greenhouse, Lever, Taleo, iCIMS or any other commercial ATS. Each is one instance of its variable — one two-column arrangement, one icon setting, four heading substitutions — not an exhaustive survey. The full raw output, the fixture generator and the comparison logic are in the repository and reproducible by anyone who runs it.

Last reviewed against the engine source: 2026-09-19.

🚀 Share this resource

💙 Help someone else with their job search.

👀 Preview

I found this useful and thought it might help with your job search. https://atsresumekit.com/guides/ats-resume-format

🚀 Help a Job Seeker

Found this useful? Share ATSResumeKit on LinkedIn or social media. Your one share could help someone create a better resume and get closer to their next job.

❤️ Thanks for helping us reach more job seekers!