How to Make an ATS-Friendly Resume in LaTeX
A tracking system reads your resume as plain text before any person sees it, so what matters is not how the PDF looks but what falls out of its text layer. LaTeX is fine at this: every engine writes a real text layer. What breaks is layout. Two columns, a name drawn inside a graphic, skills in a table grid, and dates in a side rail all survive the eye and fail the parser.
Watch a layout choice break the parse
Turn each choice on and read the right-hand side. That column is not a simulation of a vendor, it is what text extraction yields, which is the first thing any tracking system does with your file.
Turn a layout choice on and watch the parse
The left side is what a person sees. The right side is what comes out of the text layer, which is what a tracking system reads first.
What a person sees
Ayesha Rahman
ayesha@example.edu · Dhaka · github.com/arahman
Experience
Research Assistant, BRAC University
2024 to 2026
Built a retrieval pipeline over 12k lab documents.
Skills
Python | PyTorch | LaTeX | Postgres
What the parser gets
One column, real text, dates beside their roles. Every field comes out in the order it was written.
Check your own file in one command
You do not have to trust an article about this, including this one. Poppler ships pdftotext, and running it against your own resume shows you precisely what a parser receives:
pdftotext -layout resume.pdf - | head -40Read the output as a stranger would. Is your name the first line? Do the dates sit beside the roles they belong to? Did your skills survive as separate words? Drop the -layout flag and run it again, because some parsers do not preserve layout at all, and that is the harsher and more revealing test.
The rules that actually matter
- One column for anything that must be read. A sidebar for a photo is survivable. A sidebar holding your employment dates is not.
- Real text everywhere, including the header. A name set inside a TikZ banner or an included image extracts as nothing, and the field a recruiter searches by is the one you lost.
- Lists, not grids. A skills grid built from
tabularoften extracts with no separator at all. - Standard section names. Experience, Education, Skills, Publications. A section called "Where I have been" is a section nothing matches.
- Dates next to their roles, in one format. Pick "2024 to 2026" or "2024 - 2026" and hold it. Mixed formats within one file are a common cause of missing employment history.
None of this requires an ugly document. Every rule above is about where text sits in the page structure, not about typography, and a single-column resume with good spacing and a real typeface reads better to a human than a crowded two-column one anyway.
Getting there without rewriting it yourself
If you already have a resume with the risky choices in it, the work is mechanical: collapse the columns, pull the header text out of the graphic, turn the grid into a list. That is the kind of edit Lexi is good at, because every step is a rule rather than a judgment. The prompts below are the ones that produce the edit rather than a description of it.
What you want
Make this CV single column. Keep every section and every date, and put the dates on the same line as the role they belong to.
Why this wording. It names what must be preserved. "Make this ATS friendly" is a judgment call the model has to guess at, and guessing is where content goes missing.
What runs
- read_file
- propose_edit
- compile
What changes in the file
- \begin{paracol}{2}- \switchcolumn+ % single column: dates inline with each role
Ask it the vague way instead. Ask it to "improve the formatting" and you get a different font and the same two columns.
Every tool sequence here is what Lexi actually emits for that ask.
Start from a template that already parses
Easier than repairing one: begin with a single-column layout. The CV and resume templates include plenty of them, and the resume template roundup sorts them by career stage and country, since a German Lebenslauf and a US resume are not the same document. Whichever you pick, run the pdftotext check on the compiled file before you send it anywhere.
Frequently asked questions
Does LaTeX work with applicant tracking systems?
Yes, as long as the PDF has a real text layer, which pdflatex, xelatex and lualatex all produce. What breaks parsing is layout, not LaTeX: multiple columns, text drawn inside images, and content laid out in tables. A single-column LaTeX resume extracts cleanly.
How do I check whether my resume is ATS-friendly?
Run pdftotext on your own PDF and read the output. That is the same first step a tracking system takes. If the field order is scrambled, your name is missing, or your skills run together into one word, that is exactly what the system receives.
Are two-column resume templates bad for ATS?
They are risky. Text extraction follows visual order, so a two-column layout interleaves the columns: a job title from the right column lands between two lines from the left. A human reads the columns separately; the parser does not.
Should I avoid tables in a LaTeX resume?
Avoid them for content you need parsed, such as skills and dates. Cells frequently extract with no separator, so "Python | PyTorch | LaTeX" becomes one run-on token. Use a simple list or comma-separated line instead.
Do icons for email and phone cause problems?
Often. Icon fonts place glyphs in the Unicode private use area, which extracts as a box or as nothing. Keep the address itself as real text and treat the icon as decoration beside it.
Ready to try LetX?
Join researchers and students focusing on their work, not the tools.
Get Started FreeWritten by Shihab Shahriar Antor , AI Engineer & Founder of Shahriar Labs. Builder of LetX (collaborative LaTeX) and QuantumSketch (AI STEM video).
