# Why LuaLaTeX Is Used for CVs and XeLaTeX for Cover Letters in ai-job-search

> Learn why ai-job-search uses LuaLaTeX for CVs to prevent font expansion errors and XeLaTeX for cover letters to support custom system fonts via fontspec.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: internals
- Published: 2026-08-31

---

**The ai-job-search repository compiles CVs with LuaLaTeX to avoid font-expansion errors with the `fontawesome5` package, while cover letters require XeLaTeX because the `cover.cls` template depends on `fontspec` for custom system fonts.**

When generating application documents, this repository explicitly separates LaTeX engines by document type. The distinction ensures reliable compilation across different LaTeX distributions, particularly MiKTeX, while supporting modern font features required by each template.

## Why LuaLaTeX Is Required for CV Compilation

The CV template relies on the `moderncv` document class coupled with the `fontawesome5` icon font. Standard pdfLaTeX often crashes when processing these Unicode-heavy OpenType fonts.

### The Fontawesome5 Font-Expansion Problem

On recent MiKTeX installations, `pdflatex` frequently fails with *font-expansion* errors when rendering `fontawesome5` glyphs. According to [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md) at line 67, *"pdflatex often fails on modern MiKTeX installs with `fontawesome5` font-expansion errors"*. LuaLaTeX handles modern Unicode fonts and OpenType features natively, bypassing these specific rendering crashes.

### ModernCV Class and Unicode Font Handling

LuaLaTeX processes the stock CV sources located in `cv/main_example.tex` without the micro-typography issues that plague pdfLaTeX. The engine provides clean access to font expansion and rendering logic required by the `moderncv` class, making it the default choice for the curriculum vitae pipeline as documented in [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md) around line 53.

## Why XeLaTeX Is Required for Cover Letters

The cover letter template uses a custom class file that imports system fonts unavailable to traditional LaTeX engines.

### Fontspec Dependency in cover.cls

The file `cover_letters/cover_example.tex` invokes `cover.cls`, which loads the `fontspec` package. As noted in [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md), *"the cover letter compiles with `xelatex` because `cover.cls` requires `fontspec`"*. This package mandates an engine capable of understanding system font paths and Unicode encoding—functionality provided by XeLaTeX (or LuaLaTeX, though the project standardizes on XeLaTeX here).

### Custom Font Requirements (Lato/Raley)

The cover letter design specifically imports the `Lato` and `Raleway` font families. These custom system fonts require the `fontspec` interface to map TrueType/OpenType files correctly within the document structure, a capability XeLaTeX handles reliably for this specific template architecture.

## CI/CD Implementation and Build Commands

The continuous integration pipeline enforces these engine choices through explicit job definitions in [`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml) (lines 148–161).

To compile documents locally using the repository's prescribed methods:

```bash

# Compile the CV with LuaLaTeX

cd cv && lualatex -interaction=nonstopmode -halt-on-error main_example.tex && cd ..

# Compile the cover letter with XeLaTeX

cd cover_letters && xelatex -interaction=nonstopmode -halt-on-error cover_example.tex && cd ..

```

The CI workflow mirrors these commands exactly, ensuring that `cv/main_example.tex` always processes through `lualatex` and `cover_letters/cover_example.tex` through `xelatex` to prevent build failures.

## Key Configuration Files

Understanding the engine selection requires examining these specific source files:

- **`cv/main_example.tex`** – Sample CV source requiring LuaLaTeX for `fontawesome5` compatibility
- **`cover_letters/cover_example.tex`** – Cover letter source requiring XeLaTeX due to `fontspec` usage
- **[`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md)** – Documents the rationale and compilation commands (line 53)
- **[`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml)** – Enforces engine-specific builds (lines 148–161)

## Summary

- **LuaLaTeX** is selected for CV compilation to avoid `fontawesome5` font-expansion crashes that occur with pdfLaTeX on modern MiKTeX systems.
- **XeLaTeX** is required for cover letters because `cover.cls` uses `fontspec` to load custom system fonts like Lato and Raleway.
- The CI pipeline explicitly separates build commands in [`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml) to maintain these requirements.

## Frequently Asked Questions

### Can I use pdfLaTeX instead of LuaLaTeX for the CV?

No. According to the repository documentation in [`README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/README.md), pdfLaTeX often fails on modern MiKTeX installations due to font-expansion errors when processing the `fontawesome5` icon font used by the `moderncv` class. LuaLaTeX handles these modern Unicode fonts without errors.

### Why doesn't the cover letter use LuaLaTeX instead of XeLaTeX?

While LuaLaTeX also supports `fontspec`, the `cover.cls` template was written with XeLaTeX-specific assumptions and conventions. The repository standardizes on XeLaTeX for cover letters to ensure consistent rendering of the Lato and Raleway custom fonts across different environments.

### Where are the compilation commands defined in the repository?

The build commands are documented in [`SETUP.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SETUP.md) around line 53 and enforced programmatically in [`.github/workflows/ci.yml`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.github/workflows/ci.yml) at lines 148–161. The CI workflow explicitly calls `lualatex` for `cv/main_example.tex` and `xelatex` for `cover_letters/cover_example.tex`.

### What fonts cause issues with pdfLaTeX in this setup?

The `fontawesome5` icon font causes font-expansion errors when compiled with pdfLaTeX, particularly on recent MiKTeX distributions. Additionally, the cover letter's reliance on system fonts (Lato and Raleway) through `fontspec` makes pdfLaTeX incompatible for that document type as well.