\begin{article}
The Complete Guide to LaTeX Engines: pdfLaTeX, XeLaTeX, LuaLaTeX, and latexmk
A practical comparison of all four LaTeX engines — what each one does, when to use it, and how to select the right engine via the FormaTeX API.

LaTeX is not a single compiler — it is a family of engines that share the same document format but differ in capabilities, speed, and output quality. Picking the wrong engine is one of the most common sources of compilation errors. This guide covers all four engines FormaTeX supports and gives you a decision framework.
Four Engines Overview
The four engines have a historical progression: pdfLaTeX was the standard for decades, XeLaTeX added Unicode and font support, LuaLaTeX added programmability, and latexmk is not a compiler at all — it is a build manager that runs the right engine the right number of times.
| Engine | Year | Language | Unicode | Custom Fonts | Scripting |
|---|---|---|---|---|---|
| pdfLaTeX | 1997 | C | Via inputenc | Limited | No |
| XeLaTeX | 2004 | C/Obj-C | Native | Full (OpenType) | No |
| LuaLaTeX | 2007 | C+Lua | Native | Full (OpenType) | Yes (Lua 5.3) |
| latexmk | 1998 | Perl | Inherits | Inherits | No |
pdfLaTeX Deep Dive
pdflatex is the default, fastest, and most compatible engine. It generates PDF directly without an intermediate DVI step. If you do not have a specific reason to use another engine, start here.
\documentclass{article}
\usepackage[utf8]{inputenc} % required for pdflatex
\usepackage[T1]{fontenc} % required for pdflatex
\usepackage{microtype} % enables microtypography
\begin{document}
Standard document. All CTAN packages work here.
\end{document}Strengths:
- Fastest compilation time (typically 2–5× faster than LuaLaTeX)
- Widest package compatibility — every CTAN package supports pdflatex
- Required by most academic journals (IEEE, ACM, arXiv default)
- Available on the FormaTeX free plan
Limitations:
- Requires
inputencfor UTF-8 characters - Limited to fonts converted to Type 1 or TrueType
- No Lua scripting
curl -X POST https://api.formatex.io/api/v1/compile \
-H "X-API-Key: $FORMATEX_KEY" \
-d '{"engine":"pdflatex","content":"..."}'XeLaTeX Deep Dive
xelatex was built to fix pdfLaTeX's font limitations. It uses the system's native font rendering (HarfBuzz) and supports any OpenType or TrueType font.
\documentclass{article}
\usepackage{fontspec} % replaces inputenc+fontenc
\setmainfont{TeX Gyre Termes} % any system or bundled OTF/TTF
\begin{document}
Native Unicode — no inputenc needed.
Arabic: مرحبا. Hebrew: שלום. CJK: 你好.
\end{document}Strengths:
- Native Unicode — write any language without encoding packages
- Full OpenType font access via
fontspec - Right-to-left languages via the
bidipackage - Better for multilingual documents
Limitations:
- ~30–50% slower than pdflatex
- Some older font packages conflict with fontspec
- Requires Pro plan on FormaTeX
Remove \usepackage[utf8]{inputenc} when switching from pdflatex to xelatex. They are incompatible — including both causes a package clash error.
LuaLaTeX Deep Dive
lualatex has the same font capabilities as XeLaTeX but embeds a full Lua 5.3 interpreter. This enables programmatic document generation that is impossible in the other engines.
\documentclass{article}
\usepackage{fontspec}
\usepackage{luacode}
\begin{document}
\begin{luacode}
-- Generate a multiplication table programmatically
for i = 1, 5 do
for j = 1, 5 do
tex.sprint(i * j)
if j < 5 then tex.sprint(" & ") end
end
tex.sprint(" \\\\")
end
\end{luacode}
\end{document}Strengths:
- Full Lua scripting — loops, conditionals, string manipulation inside documents
- Same font support as XeLaTeX
- Access to TeX internals via the Lua FFI
- Ideal for template-driven, data-heavy documents
Limitations:
- Slowest engine — typically 2–4× slower than pdflatex
- Requires Pro plan on FormaTeX
- Less package compatibility than pdflatex (though much improved)
latexmk Deep Dive
latexmk is not a compiler — it is a build coordinator written in Perl. It determines which engine to run, how many times, and in what order to resolve all cross-references and bibliography entries.
A document with a bibliography requires:
- Run pdflatex (generates
.auxfile) - Run biber or bibtex (generates
.bblfile) - Run pdflatex again (incorporates bibliography)
- Run pdflatex again (resolves references)
latexmk automates this entire sequence:
\documentclass{article}
\usepackage[backend=biber]{biblatex}
\addbibresource{refs.bib}
\begin{document}
As shown by \cite{knuth1984tex}, TeX is powerful.
\printbibliography
\end{document}# latexmk handles the multi-pass compilation automatically
curl -X POST https://api.formatex.io/api/v1/compile \
-H "X-API-Key: $FORMATEX_KEY" \
-d '{"engine":"latexmk","content":"..."}'Strengths:
- Handles bibliography automatically (BibTeX, Biber)
- Resolves cross-references, indexes, and glossaries
- Eliminates "run pdflatex three times" errors
- Detects which engine your document actually requires
Limitations:
- Slower than running pdflatex directly (multiple passes)
- Requires Pro plan on FormaTeX
Use latexmk whenever your document has a \bibliography{} or \addbibresource{} command. Without it, you will get [?] placeholders instead of citation text.
Decision Matrix
| Your document needs | Engine to use |
|---|---|
| Fast compilation, standard packages | pdflatex |
| Custom fonts (TTF/OTF) | xelatex |
| Non-Latin scripts (Arabic, CJK, Hebrew) | xelatex |
| Lua scripting / programmatic content | lualatex |
| Bibliography / citations | latexmk |
| Cross-references, index, glossary | latexmk |
| Journal submission (IEEE, ACM, arXiv) | pdflatex |
Engine Selection via the API
type Engine = "pdflatex" | "xelatex" | "lualatex" | "latexmk";
function chooseEngine(options: {
hasBibliography: boolean;
hasLuaCode: boolean;
needsCustomFonts: boolean;
hasNonLatinScript: boolean;
}): Engine {
if (options.hasBibliography) return "latexmk";
if (options.hasLuaCode) return "lualatex";
if (options.needsCustomFonts || options.hasNonLatinScript) return "xelatex";
return "pdflatex";
}
const response = await fetch("https://api.formatex.io/api/v1/compile", {
method: "POST",
headers: {
"X-API-Key": process.env.FORMATEX_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
engine: chooseEngine({ hasBibliography: true, hasLuaCode: false, needsCustomFonts: false, hasNonLatinScript: false }),
content: latexSource,
}),
});Plan Requirements
| Engine | Minimum Plan |
|---|---|
pdflatex | Free |
xelatex | Pro |
lualatex | Pro |
latexmk | Pro |
- Sign up for free —
pdflatexwith 15 compilations/month - Upgrade to Pro — all four engines, 500 compilations/month
- Read the API docs — full endpoint reference
\end{article}
\related{posts}




