My custom CV builder

My custom CV builder
Photo by Andrew Neel / Unsplash

I have a very customized CV building pipeline that helps me churn out a clean, customized CV in a matter of minutes. It was born out of necessity of when I went on job hunting and had to tailor each submission to the JD posted. I'm sharing because I feel like this can be a sort of inspiration for people out there.

The CV builder market

In the market there are a bunch of graphical CV builder, and I have tried several of them. They are all very cool projects, and serves their intended target well. For most professions out there, you usually have a list of most presentable projects & skills that you can share with all the prospective employers without making a lot of modifications.

However, I feel like submitting CVs in software engineering is a whole different problem. Each time I need to apply for a job, I just have to change the wording of every entry in the résumé just so it shows that I know the exact tech-stack they are hiring. I would call those different aspects of the previous projects/positions. For example, in my previous backend engineer role, I had to deal with a plethora of Node.js/Python/Golang projects with respective frameworks. So when I apply for a new Node.js position, we just have to cut out the Python/Golang parts.

At any rate, the thing I found most lacking in all those GUI-based CV builder is modularity, or building-blocks. I consider my experiences as a list of entries, and each résumé just a view into a subset of those entries. There are going to be a lot of reuse & minor modification between CV instances I sent out to companies.

And then the allure of a simple LaTex built CV. I have had very good reaction from hiring people when I submitted a LaTex document. Mainly because it's so clean & academic looking, which makes me look smart.

Now the goal is to make a modular solution on top of LaTex or something similar.

Something similar to LaTex

LaTex is such a cool & smart thing to work with. I hate every single minute of working with LaTex. The LaTex workflow consists of 1 hour of searching for an online solution + 30 minutes of copy-pasting and markup wrangling to make it render a list of data. Because LaTex is a markup language, not an imperative programming language, you will never be able to make it reasonably loops over something.

So I found that something similar to LaTex but infinitely easier to work with, which is Typst. They are promoting themselves as an app, but at the core, it is a command line interpreter that spit out a PDF file.

The Typst language is a mix between Python/Ruby-ish scripting and Markdown, which is called code-mode and markup-mode. A Typst file consist of blocks of code & markup, which can contain each other. So you can do a for-loop of a markup block, and voilà, you have a list of things built from a list. The Typst engine also have library support, so I can pull in libraries from their registry to help with my work.

I suggest checking out Typst if you have some certain use cases that you want to use LaTex for, but yourself a bit tired from dealing with the antiquated Tex syntax.

The CV building blocks

Typst has robust data wrangling capability. Which means I can import data from some sources and perform operations/rendering on those data. For the data-sources, I choose to write a bunch of YAML files. It looks somewhat like this:

data
├── avatar.jpg
├── basic.yml
├── certification.yml
├── default-config.yml
├── education.yml
├── experience.yml
├── interest.yml
├── projects.yml
├── soft-skills.yml
└── tech-skill.yml

In those files, I define the data for each CV structure. Take projects.yml for example.

- id: typst-cv-builder
  name: Typst CV builder
  description: Personal Project
  date: Apr 2024
  summary: >-
    Build a simple command-line based CV builder
    Use [Typst](https://typst.app) as the typesetting engine.
    

    **Key features**:
    - Pulling CV resources (projects, experiences, skills, ...) from a set of files. 
    - Define a CV instance using YAML with references to those resources.
    - Fast, customizable

The file is an Array of those project entries. Each entry has an id for reference and a bunch of other fields for displaying. The large field summary is going to be rendered as Markdown, using the cmarker.typ library (have I mentioned Typst having library supports)

The CV definition

I also settled on defining each CV instance as a YAML file. The workflow is, when I need to create a new customized CV for a position, I create a new YAML file like this:

# Cyberdyne-AI-Engineer-2024.yaml

lang: "en"

positions:
  - AI Engineer


about: >-
  Relentless, precise, and equipped with an unbreakable focus on optimization, I bring the same level of determination to software engineering as I once did to terminating targets. Immune to burnout, I excel in hunting down complex bugs and eliminating inefficiencies. Whenever faced with difficulties, I'll be back until I can say Hasta la Vista to the issue.

experiences:
  - skynet
  - the-resistance

projects:
  - sarah-connor-protection-detail
  - john-connor-protection-detail

sections:
  - about
  - languages
  - experiences
  - projects
  - tech-skills
  - soft-skills
  - interests
  - certifications

Each of the section has references to the entries I defined in the step above. There are also some preambles (language, applying position, the about section). Finally, there is a part where I can re-arrange the sections (or optionally, leave some section out)

The CV template

This is the part where I define the CV in Typst. This Typst code is responsible for loading the data & CV definition, do the lookup & render it out. I build my CV template based on another template on Typst marketplace, with my own customization. It can't get much simpler than that. The code is too complex to discuss here, so if you are interested, checkout my repository: https://github.com/antran22/typst-cv-builder

Extras

I address the different aspects of CV entries with a rough, single level inheritance. If an entry extends from another, I can change some field on top of that. For example, given a project entry like this:

- id: defense-system
  name: Defense System
  description: with Cyberdyne Systems
  date: Oct 2023 - Feb 2024
  summary: >-
    yadda yadda
    ...
    some stuffs
  keywords:
    - AI
    - Defense System

Obviously, it is a very big system, with frontend & backend work done on it. If I am applying for a frontend position, I only want to showcase my frontend skill:

- id: defense-system-frontend
  name: Defense System Frontend
  inherit: defense-system
  summary: >-
    yadda yadda
    ...
    some frontend stuffs
  keywords:
    - AI
    - Defense System
    - Frontend

Afterthought

It was more of a quick & rudimentary bunch of scripts I tie in together to help me in my job search. It serves my current needs well and give me a lot of control over my data. If you are interested in trying out, checkout the source code on Github:

GitHub - antran22/typst-cv-builder: A CV Builder, using Typst as the rendering engine.
A CV Builder, using Typst as the rendering engine. - antran22/typst-cv-builder