Using LaTeX for Resumes

September 8, 2022

LaTeX is a programming language built on the TeX typesetting system. It’s most commonly used in academia, and often used by Software Engineers for creating resumes. I ended up creating LatexResume to simplify the process of writing resumes.


What we’re looking for

To create resumes in LaTeX the perfect solution should:

Exploring options

We have a few options when we want to start creating a resume:

  1. Overleaf is a fully featured LaTeX editor that we can use. It hosts a lot of pre-built templates, and has an editor similar to the one we’re looking for. However, I’m put off by the account requirement and lack of API.
  2. Resumake is another website that lets us create resumes using templates. It doesn’t allow the same amount of flexibility as Overleaf, but is open source.
  3. Build a solution in-house: Using a template available on GitHub, I can use pdfLaTeX to quickly build PDFs from .tex documents. Since every project is incomplete without classic over-engineering, I will build a website as well.

Building in-house

I picked up a template shared by Sourabh Bajaj on GitHub. I’ve seen it in use quite a bit and the README has all the instructions we need to build the resume PDF from the .tex source.

Running pdfLaTeX

Documents written in LaTeX can be rendered as PDF using LaTeX engines similar to pdfLaTeX which we’ll use. The above repository contains a Dockerfile that can be used to run pdfLaTeX easily:

docker run --rm -i -v "$PWD":/data latex pdflatex resume.tex

This is super convenient to run LaTeX but it uses texlive-full which needs at least 7 GiB disk space. If you’re running locally, you may face issues due to lack of disk space, slow internet or limited bandwidth. Running it on CI systems, you may again run into the same issues depending on the provider.

Integrating with CI

Using this repository as a starting point, we can wire up any CI tool to build the container image locally and build a PDF. On GitLab, the .gitlab.yml file will look something like this:

  image: docker:latest
  stage: build
    - docker:dind
    - apk add --no-cache git
    - git config --global user.name "John Doe"
    - git config --global user.email "[email protected]"
    - docker pull registry.gitlab.com/$GIT_USER_ID/resume:latest
    - docker run --rm -i -v "$PWD":/data $image_uri pdflatex resume.tex
    - git add .
    - git commit -m "[ci skip] Update resume"
    - git remote set-url origin https://gitlab-ci-token:${PERSONAL_ACCESS_TOKEN}@gitlab.com/jdoe/resume.git
    - git push origin HEAD:main

In the above pipeline, we’re pulling a pre-built image we’ve pushed to the GitLab registry earlier, and using it to generate resume.pdf. The resume then gets committed to the repository with [ci skip] in the subject to avoid ending up in an endless loop.

For folks who use GitHub, I will share a similar workflow for Actions near the end.

We can do better! Building LatexResume

While the above solution works great, it can still be improved. I wrote a small API that could accept a file and return a rendered PDF as response, and a side-by-side editor using React that could let me write LaTeX and generate the PDF preview immediately.

You can use cURL on the terminal to convert a resume you have on disk to PDF instantaneously:

curl --fail --show-error -X 'POST' 'https://latexresume.com/api/v1/resume'  \
    -F '[email protected]' --output resume.pdf

And the React app itself is accessible by going to LatexResume.com.

A screenshot of the LatexResume website

I’m sure I’m missing some edge cases, but so far it’s worked for me without issues.


To finish things off, we can replace the Docker image build in our CI pipeline to utilize the LatexResume API instead. For GitHub Actions:

name: CI
    branches: [ main ]
    runs-on: ubuntu-latest
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: sudo apt -y update && sudo apt install -y curl git
      - name: Build resume
        run: |
          curl --fail --show-error -X 'POST' 'https://latexresume.com/api/v1/resume' -F '[email protected]' --output resume.pdf
      - name: Update resume
        run: |
          git config --global user.name 'John Doe'
          git config --global user.email '[email protected]'
          git add .
          git commit -m "[ci skip] Update resume"
          git push

That’s it! Let me know if you find the website useful.