UT Resume AI
A resume-parsing tool that turns an uploaded PDF, DOCX, or TXT resume into structured JSON — local text extraction feeding a locally-run LLM instead of a brittle regex-and-templates approach or a cloud API.
- Period
- Winter 2026
- Role
- Solo
- Stack
- Next.js · TypeScript · Tailwind CSS · Ollama · pdf-parse · mammoth
- Source
- Repository
The problem
Resumes are semi-structured at best: the information (education, experience, skills) is consistent, but the formatting isn’t — different section orders, different date formats, single- and multi-column layouts. A regex-and-templates parser breaks the moment a resume departs from whatever layout it was written against, which is most resumes.
What I built
A Next.js app where a user uploads a resume (PDF, DOCX, or TXT), the file is converted to
plain text locally (pdf-parse/pdfjs-dist for PDFs, mammoth for DOCX), and the extracted text
is handed to a locally-run LLM through Ollama to parse into structured JSON — education,
experience, and skills as distinct fields rather than one blob of text. Running the model through
Ollama rather than a cloud API means resume content never leaves the machine it’s running on.
The extraction and parsing steps are deliberately separate stages rather than one opaque call:
extract.ts owns turning the uploaded file into text, and the LLM parsing step owns turning that
text into structured fields. Keeping them separate means a bad result can be traced to the stage
that produced it — a garbled text extraction looks different from a well-extracted resume the LLM
mis-parsed.
Testing
Two dedicated test routes cover the pipeline’s two stages independently: test-education.ts
exercises the education-field parsing specifically, and test-llm.ts exercises the LLM call in
isolation from the upload/extraction flow around it. Testing each stage on its own — rather than
only ever running the full upload-to-JSON pipeline — is what makes it possible to tell whether a
bad result came from extraction or from parsing.
What I’d do next
- Add ground-truth comparison. Right now correctness is checked by inspection; a small set of resumes with hand-labeled expected fields would turn that into an actual accuracy number.
- Handle multi-column and scanned resumes explicitly — the layouts most likely to break the extraction stage.