XeLaTeX: Unicode, System Fonts and When to Use It
Quick answer
- What it is: LaTeX on the XeTeX engine, with native Unicode input and any installed OpenType/TrueType font.
- Fonts:
\usepackage{fontspec}and\setmainfont{Times New Roman}(also\setsansfont,\setmonofont). - Languages:
polyglossia(or babel) for hyphenation and right-to-left scripts;xeCJKfor Chinese, Japanese and Korean. - Drop from pdfLaTeX preambles:
\usepackage[utf8]{inputenc}and\usepackage[T1]{fontenc}. - Compile:
latexmk -xelatex main.tex. Octree picks XeLaTeX automatically when the document usesfontspec.
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Times New Roman}
\begin{document}
Unicode typed directly: café, naïve, Straße, Ελληνικά, Привет, €, ½.
\end{document}XeLaTeX is one of the three engines that turn LaTeX into a PDF, alongside pdfLaTeX and LuaLaTeX. Its two strengths are Unicode and fonts: you can type any character straight into the source and set the document in any font installed on the system, which pdfLaTeX cannot do. This guide compares the three engines, shows how to set fonts with fontspec, write in other scripts with polyglossia and xeCJK, what to change when moving a pdfLaTeX document to XeLaTeX, and how to fix the errors you will meet.
XeLaTeX vs pdfLaTeX vs LuaLaTeX
| pdfLaTeX | XeLaTeX | LuaLaTeX | |
|---|---|---|---|
| Input | UTF-8, but only characters the font encoding covers | Full Unicode | Full Unicode |
| Fonts | TeX fonts via packages (lmodern, newtx) | Any installed OpenType/TrueType font via fontspec | Same as XeLaTeX via fontspec |
| Non-Latin scripts | Limited (Cyrillic, Greek with setup) | Arabic, Hebrew, Indic, CJK and more | Same, plus advanced shaping control |
| Speed | Fastest | Fast | Slowest |
microtype | Protrusion and font expansion | Protrusion only | Protrusion and font expansion |
| Scripting | No | No | Lua inside the document |
| Best for | Journal and arXiv submissions, standard fonts | System fonts, multilingual and CJK documents | Like XeLaTeX, plus Lua and complex font features |
The LaTeX markup itself does not change between engines: sections, math, tables and references work the same. What changes is the font setup in the preamble and a handful of packages tied to one engine. If a document compiles with pdfLaTeX and you do not need other fonts or scripts, there is no reason to switch.
How to Compile with XeLaTeX
On the command line, run xelatex instead of pdflatex, or let latexmk handle the reruns. -synctex=1 writes the SyncTeX file that links PDF and source, the same as with pdfLaTeX:
xelatex -synctex=1 main.tex # one run
latexmk -xelatex -synctex=1 main.tex # all runs, plus bibliographyIn Octree there is no setting to change: the compiler scans the project's .tex, .sty and .cls files and switches to XeLaTeX when it finds \usepackage{fontspec}, \setmainfont (or \setsansfont, \setmonofont, \newfontfamily), \usepackage{polyglossia}, \usepackage{xeCJK}, \setCJKmainfont or \usepackage{unicode-math}. LuaLaTeX takes precedence when the source uses \directlua or luacode. Anything else, including a document that only uses the ctex classes, compiles with pdfLaTeX; add \usepackage{fontspec} to switch it. To print the engine's logo, load metalogo and write \XeLaTeX.
System Fonts with fontspec
fontspec loads fonts by their name. Set the three document families once in the preamble; bold and italic are found automatically when the font family has them:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Times New Roman} % serif body text
\setsansfont{Arial} % \textsf and sans headings
\setmonofont{Courier New} % \texttt and verbatim
% An extra family with its own command
\newfontfamily\headingfont{Arial}[LetterSpace=5]
\begin{document}
{\headingfont\Large REPORT}
Body text in Times New Roman, \textbf{bold}, \textit{italic},
\textsf{sans serif} and \texttt{monospaced}.
\end{document}A font name works only if the font is installed where the document compiles. On Octree, the Microsoft core fonts (Times New Roman, Arial, Courier New, Georgia, Verdana) and the TeX Gyre and Noto families, including Noto CJK, are installed, and any font in TeX Live can be loaded by its file name. To use a font that is not available, upload the font files to the project and load them by file name with Path:
\documentclass{article}
\usepackage{fontspec}
% Loading by file name. For files uploaded to the project, add Path=./fonts/
\setmainfont{texgyretermes}[
Extension = .otf,
UprightFont = *-regular,
BoldFont = *-bold,
ItalicFont = *-italic,
BoldItalicFont = *-bolditalic,
Numbers = OldStyle,
]
\begin{document}
TeX Gyre Termes, a free Times clone, with old-style figures: 1234567890.
\textbf{Bold} and \textit{italic} come from the files named above.
\end{document}Font features go in the brackets after the name: Numbers=OldStyle, Scale=MatchLowercase to match a second font's x-height, Color=blue, LetterSpace=5. For sizes, the usual commands still apply; see font size.
Unicode Input and Math
With XeLaTeX the source file is read as UTF-8 and every character goes straight to the font. Accented letters, Greek, Cyrillic, symbols such as € and ½ can be typed directly, as long as the font has them. Latin Modern, the default, covers Latin-script languages but not Greek, Cyrillic, Chinese or Arabic; for those, set a font that has them, such as Times New Roman or Noto Serif. For math in Unicode, unicode-math replaces the old math fonts with an OpenType math font and lets you type symbols such as α, ≤ or ∫ in math mode:
\documentclass{article}
\usepackage{amsmath}
\usepackage{unicode-math}
\setmathfont{latinmodern-math.otf} % or {STIX Two Math}, {TeX Gyre Termes Math}
\begin{document}
Unicode in text: Ångström, Dvořák, Łódź, Þórr, œuvre.
Unicode in math: $α + β ≤ ∑_{i=1}^{n} x_i^2$ and $∫_0^1 f(x)\,dx ≠ ∞$.
The same with commands: $\alpha + \beta \le \sum_{i=1}^{n} x_i^2$.
\end{document}Load unicode-math after amsmath and do not load amssymb or other math font packages with it; the OpenType math font already contains those symbols. For the commands behind each symbol, see Greek letters and math symbols.
Languages and Right-to-Left Text: polyglossia
polyglossia sets hyphenation, captions (“Inhaltsverzeichnis” for German) and text direction for each language. For a script that the main font lacks, give the language its own font with \newfontfamily:
\documentclass{article}
\usepackage{fontspec}
\usepackage{polyglossia}
\setdefaultlanguage{english}
\setotherlanguages{arabic,german}
\newfontfamily\arabicfont[Script=Arabic]{Amiri-Regular.ttf}
\begin{document}
English text with a German phrase: \textgerman{Grüße aus München}.
\begin{Arabic}
مرحبا بالعالم. هذا نص عربي من اليمين إلى اليسار.
\end{Arabic}
Inline Arabic: \textarabic{السلام عليكم}.
\end{document}Babel works with XeLaTeX too and is now the more actively developed option; its \babelprovide and \babelfont commands do the same job. Pick one of the two, not both.
Chinese, Japanese and Korean: xeCJK
xeCJK handles CJK text inside a Latin document: it switches font automatically for CJK characters and applies the right line-breaking rules. Set a CJK font with \setCJKmainfont:
\documentclass{article}
\usepackage{xeCJK}
\setCJKmainfont{FandolSong-Regular.otf} % on Octree also {Noto Serif CJK SC}
\begin{document}
English and 中文 in the same paragraph. 这是一个使用 XeLaTeX 编译的中文示例,
标点符号和换行由 xeCJK 处理。
\end{document}For a document mainly in Chinese, the ctex classes (\documentclass{ctexart}) build on xeCJK and also translate headings and dates. Without a CJK font, XeLaTeX does not stop: it writes “Missing character: There is no 中 (U+4E2D) in font” to the log and leaves a gap.
What Breaks When You Switch from pdfLaTeX
Most documents compile unchanged. These are the parts of a pdfLaTeX preamble to remove or replace:
| pdfLaTeX preamble | Under XeLaTeX | Do instead |
|---|---|---|
\usepackage[utf8]{inputenc} | Ignored, with a warning | Remove it |
\usepackage[T1]{fontenc} | Switches back to 8-bit TeX fonts | Remove it; fontspec sets the encoding |
\usepackage{times}, mathptmx, lmodern | Work, but bypass fontspec | \setmainfont{...}; unicode-math for math |
\usepackage[pdftex]{graphicx}, [pdftex]{hyperref} | Errors: the pdftex driver needs pdfTeX | Drop the driver option; it is detected |
\pdf... primitives such as \pdfminorversion | Undefined control sequence | Remove, or test the engine with the iftex package |
microtype font expansion | Not available | Protrusion still works; use LuaLaTeX if you need expansion |
To keep one source that compiles with either engine, branch on the engine with iftex:
\documentclass{article}
\usepackage{iftex}
\ifPDFTeX
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\else
\usepackage{fontspec} % XeLaTeX or LuaLaTeX
\setmainfont{texgyretermes}[Extension=.otf, UprightFont=*-regular,
BoldFont=*-bold, ItalicFont=*-italic, BoldItalicFont=*-bolditalic]
\fi
\begin{document}
This compiles with pdfLaTeX, XeLaTeX and LuaLaTeX.
\end{document}Common Errors and Fixes
| Message or symptom | Cause | Fix |
|---|---|---|
| Fatal Package fontspec Error: The fontspec package requires either XeTeX or LuaTeX | The document was compiled with pdfLaTeX | Compile with XeLaTeX or LuaLaTeX (latexmk -xelatex); Octree switches automatically |
| Package fontspec Error: The font “Times New Roman” cannot be found | The font is not installed on the machine that compiles, or the name is misspelled | Check the exact name (fc-list on Linux), upload the font files and load them with Path, or use a TeX Live font such as TeX Gyre Termes |
| Missing character: There is no 中 (U+4E2D) in font … (in the log, gaps in the PDF) | The current font has no glyph for that character | Pick a font that covers the script: xeCJK with a CJK font, \newfontfamily for Arabic or Hebrew |
| Package inputenc Warning: inputenc package ignored with utf8 based engines | inputenc left over from a pdfLaTeX preamble | Remove the line |
Undefined control sequence inside graphicx, or hyperref Error: Wrong driver option `pdftex' | An explicit pdftex driver option | Remove the option: \usepackage{graphicx}, \usepackage{hyperref} |
| Bold or italic falls back to regular | The font family has no bold or italic file under the name fontspec expects | Name the files: [BoldFont=..., ItalicFont=...] |
| Compilation is slow on the first run | XeLaTeX builds its font cache | Later runs are faster; nothing to fix |
Frequently Asked Questions
What is XeLaTeX?
XeLaTeX is LaTeX running on the XeTeX engine instead of pdfTeX. It reads the source as Unicode and can use any OpenType or TrueType font installed on the system through the fontspec package. The LaTeX you write is the same; only the font setup and a few engine-specific packages differ.
Should I use XeLaTeX or pdfLaTeX?
Use pdfLaTeX for English and European-language documents with the standard fonts, for journal submissions and for arXiv, which expect it. Use XeLaTeX when you need a specific system font such as Times New Roman or Arial, a non-Latin script such as Arabic, Hebrew, Chinese or Japanese, or a lot of Unicode characters typed directly. LuaLaTeX does the same as XeLaTeX and adds Lua scripting, at some cost in speed.
How do I use Times New Roman in XeLaTeX?
Load fontspec and set the main font by name: \usepackage{fontspec} and \setmainfont{Times New Roman}, then compile with XeLaTeX or LuaLaTeX. The font must be installed where the document is compiled. On Octree, Times New Roman and Arial are installed; elsewhere, TeX Gyre Termes is a free Times clone that ships with TeX Live.
Do I need \usepackage[utf8]{inputenc} with XeLaTeX?
No. XeLaTeX reads UTF-8 natively, and inputenc is ignored with the warning “inputenc package ignored with utf8 based engines”. Remove it, and remove \usepackage[T1]{fontenc} as well: fontspec sets up the font encoding itself.
Why do I get “The fontspec package requires either XeTeX or LuaTeX”?
The document loads fontspec but was compiled with pdfLaTeX, which cannot load system fonts. Switch the compiler to XeLaTeX (or LuaLaTeX): latexmk -xelatex on the command line, or the compiler setting in your editor. Octree switches to XeLaTeX automatically when the document uses fontspec.
Does SyncTeX work with XeLaTeX?
Yes. XeLaTeX writes a .synctex.gz file when you pass -synctex=1, exactly like pdfLaTeX, so clicking in the PDF jumps to the source and back. Most editors pass the option for you; on the command line add it to xelatex or latexmk yourself. Octree compiles with it on every engine for its PDF-to-source sync.
Next Steps
- LaTeX Font Size – Size commands that work with any engine
- Special Characters – Accents and symbols, with and without Unicode
- Greek Letters and Math Symbols – Commands behind the Unicode symbols
- LaTeX Commands and Macros – \newcommand, \renewcommand and \def
- Bold, Italics and Underline – Font styles inside the text
- Learn LaTeX: Tutorial for Beginners – The basics, from the first document up
Free LaTeX Tools
- LaTeX Preview – Compile a snippet and see the PDF instantly
- AI LaTeX Generator – Generate LaTeX from text descriptions
- LaTeX Symbols Reference – Browse math operators and special characters
Related Articles
Angle Brackets ⟨ ⟩: Symbol, Copy and Paste, and LaTeX
Compile LaTeX from Claude Code or Cursor with the Octree MCP Server
Diameter Symbol (⌀): Meaning, ⌀ vs Ø, and How to Type It on Windows, Mac, Word, LaTeX
LaTeX on iPad: How to Write and Compile LaTeX on a Tablet
XeLaTeX without the setup
Octree detects fontspec and compiles with XeLaTeX automatically, with Times New Roman, Arial and Noto CJK installed. Its AI editor fixes font and engine errors for you.
Try Octree Free →