Multilingual

The advice you meet most often about multilingual documents in LaTeX is “babel for pdfLaTeX, polyglossia for XeLaTeX”. That has gone stale. The babel in TeX Live 2024 is dated February 2024, supports pdfTeX, XeTeX and LuaTeX alike, assigns system fonts per language through \babelfont, and carries its own implementation of the Unicode bidirectional algorithm on LuaTeX. Count the locale data on your own disk and babel offers 297 language directories and 387 .ini files. polyglossia, meanwhile, depends on fontspec and therefore will not even start under pdfLaTeX. This page works through what you need to set a document that mixes scripts: which of the two to choose, how to switch languages, and where hyphenation and fonts fail silently — with the actual messages each failure produces.

babel vs polyglossia: which one to use

Use babel unless you have a specific reason not to. It works on every engine, ships more locale data, and is the more actively developed of the two. The babel in TeX Live 2024 is 2024/02/07 v24.2 — the version number is a calendar year because there are several releases in one. It was written by Johannes Braams and is now maintained by Javier Bezos. polyglossia is 2024/03/07 v2.1, describes itself in its own package line as modern multilingual typesetting with XeLaTeX and LuaLaTeX, and introduces itself in its README as an alternative to babel for users of those two engines. The two are therefore not equal alternatives but nested: babel covers the whole field, polyglossia covers the Unicode engines only. Load polyglossia under pdfLaTeX and the halt comes not from polyglossia but from its dependency: ! Fatal Package fontspec Error: The fontspec package requires either XeTeX or LuaTeX.

Aspectbabelpolyglossia
enginespdfTeX, XeTeX and LuaTeX alikeXeTeX and LuaTeX only (fontspec required)
locale data297 language directories and 387 .ini files (measured on TeX Live 2024)242 gloss files, advertising over 80 languages
declaring\usepackage[french,english]{babel}; the last one is the main language\setmainlanguage{...} and \setotherlanguage{...}; secondary languages must be explicit
switching\selectlanguage{...} for a block and \foreignlanguage{...}{...} inlinethe same two, plus \text plus a language name, as in \textgreek{...}
fonts\babelfont{rm}{...} assigns per language or script (Unicode engines only)fontspec commands such as \newfontfamily\greekfont{...}
bidiOn LuaTeX, bidi=basic is babel’s own Unicode implementation; on XeTeX it delegates to the bidi packagedelegates direction entirely to bidi (XeTeX) and luabidi (LuaTeX)
licenseLPPL, maintenance status maintained, Current Maintainer Javier Bezosthe MIT licence

Switching languages with selectlanguage and foreignlanguage

Use \selectlanguage{french} for a stretch of text and \foreignlanguage{french}{...} for a phrase inside a sentence. The first stays in force from that point on; the second applies only within its argument. What changes is not merely the hyphenation rules. \tableofcontents becomes “Table des matières” and the word before a chapter number becomes “Chapitre” — this is the translation of document strings, and it is where babel earns its keep in practice. More striking still, the typeset text itself changes. As measured on the page about setting Western text, Bonjour: oui! occupies 58.48572pt bare but stretches to 62.37366pt under [french]{babel}, and extracting it with pdftotext returns Bonjour : oui !. The French rule of a thin space before high punctuation has been applied as real space before the colon and the exclamation mark. Think of babel not as a tool for labelling a language but as one for applying that language’s typographic habits.

latex
% babel: the LAST option is the main language of the document
\usepackage[russian,french,english]{babel}
...
\foreignlanguage{french}{Bonjour : oui !}   % inline, one phrase
\selectlanguage{french}                     % from here on
\tableofcontents                            % now "Table des matieres"

% polyglossia (XeLaTeX / LuaLaTeX only)
\usepackage{polyglossia}
\setmainlanguage{english}
\setotherlanguage{greek}     % secondary languages must be declared
\textgreek{...}             % \text + language name

What happens when a language has no hyphenation patterns

You get a warning rather than an error, and the text is hyphenated by English rules. The reason is a constraint in TeX: hyphenation patterns cannot be loaded at run time, they are baked into the format when it is built. language.dat in TeX Live 2024 lists 87 languages once alias lines are discounted, while babel ships .ldf files for more than that, so the two sets do not match. Select Albanian with \usepackage[albanian,english]{babel} and you get Package babel Warning: No hyphenation patterns were preloaded for the language 'Albanian' into the format. followed by Now I will use the patterns preloaded for \language=0 instead. And \language=0 is Knuth’s original hyphen.tex — American English. The PDF is produced without complaint and the exit status is 0; Albanian words are simply being broken by English rules. Nothing tells you unless you read the log. The remedies are to install the package carrying that language’s patterns and rebuild the format with fmtutil, or, on a Unicode engine, to use \babelprovide[import]{...}.

Switching fonts per script: the most common failure of all

Declaring a language does not bring a font with it. This is the single most common accident in multilingual documents. Declare \setotherlanguage{russian} under XeLaTeX, write \textrussian{Русский}, and because the default Latin Modern has no Cyrillic, that passage vanishes from the page. No error is raised. The log alone carries one line per character, reading like Missing character: There is no Р (U+0420) in font [lmroman10-regular]. The exit status is 0, the PDF exists, and only the Russian is blank — as failures go, none is easier to miss. The remedy is to assign a font per script: \babelfont[russian]{rm}{...} with babel, or fontspec’s \newfontfamily\russianfont{...} with polyglossia. Note, though, that \babelfont is for Unicode engines only; call it under pdfLaTeX and you get an undefined control sequence, \babelfont ->\bbl@error@ {only-lua-xe}. To handle non-Latin scripts on pdfLaTeX the route is not fonts but fontenc encodingsT2A for Cyrillic, LGR for Greek.

latex
% XeLaTeX / LuaLaTeX: give each script a font that actually has it
\usepackage[russian,greek,english]{babel}
\babelfont{rm}{Latin Modern Roman}
\babelfont[russian]{rm}{Times New Roman}
\babelfont[greek]{rm}{Times New Roman}

% pdfLaTeX has no \babelfont: match the encoding instead
% \usepackage[T2A,LGR,T1]{fontenc}   % Cyrillic, Greek, Latin

% Without this the text is simply absent and the log says:
%   Missing character: There is no Р (U+0420) in font [lmroman10-regular]

Right-to-left text: use LuaLaTeX for Arabic and Hebrew

If you are serious about bidirectional typesetting, LuaLaTeX is the only choice. That is not a matter of taste but of where the feature lives. babel selects its bidirectional handling with the bidi= option, and bidi=basic — the mode in which babel implements the Unicode bidirectional algorithm itself — runs only on LuaTeX. Ask for it under XeLaTeX and you are told outright that the results will be wrong: ! Package babel Error: The bidi method 'basic' is available only in luatex. I'll continue with 'bidi=default', so expect wrong results. The XeLaTeX option is bidi=bidi, which delegates to the external bidi package — but merely loading it produces Package babel Warning: Some functions for 'bidi=bidi' are tentative. They might not work as expected and their behavior could change in the future. polyglossia is in the same position, since it too hands direction over to bidi and luabidi. Combine \babelprovide[import, main]{arabic} with \babelfont{rm}{...} on LuaLaTeX and a mixed Arabic and English document compiles with no warnings at all.

You can also use the bidi package directly: \setRTL (alias \setRL) turns the flow right-to-left from that point and \setLTR (alias \setLR) turns it back. Under XeTeX the direction cannot be inferred automatically, so every place where LR and RL meet needs explicit markup — and it is the sheer amount of that hand-marking that hurts. LuaTeX’s bidi=basic decides those boundaries by the Unicode rules instead, and also flips layout such as tables and margins. For a language like Persian, right-to-left but with its own conventions for digits, babel offers finer adjustments such as bidi.mapdigits. The summary is simple: for any document containing Arabic, Hebrew or Persian, starting on LuaLaTeX is in the end the quickest route.

latex
% LuaLaTeX: babel handles direction with its own Unicode implementation
\usepackage[bidi=basic]{babel}
\babelprovide[import, main]{arabic}
\babelfont{rm}{Geeza Pro}
% mixed Arabic and English needs no manual direction marks here

% XeLaTeX must delegate to the bidi package, which babel calls tentative
% \usepackage[bidi=bidi]{babel}
% \setRTL   % or \setRL  -- switch the flow right-to-left
% \setLTR   % or \setLR  -- switch it back

So how should you choose?

The decision starts not from “which languages am I mixing?” but from “which engine am I typesetting with?” A blend of Latin with some Cyrillic and Greek passes perfectly well through pdfLaTeX with babel and fontenc; but if you want system fonts, or if Arabic, Hebrew or an Indic script is involved, you need a Unicode engine. Only once that is settled does the question of babel versus polyglossia arise at all. CJK is a separate story: Japanese is the business of the pTeX-family engines and their classes, while Chinese, Korean and Japanese outside the pTeX world belong to CJKutf8, xeCJK, ctex and kotex — both have pages of their own.

  • Mostly Latin with a little Cyrillic or Greek → pdfLaTeX with babel and fontenc (T2A / LGR). No need to change an existing workflow.
  • You want system fonts, or several scripts are mixed → XeLaTeX or LuaLaTeX with babel and \babelfont.
  • Arabic, Hebrew or Persian (RTL) is involved → LuaLaTeX with babel’s bidi=basic. That mode is unavailable on XeLaTeX.
  • Reasons to pick polyglossia → you already have documents written for it, or the language you need is supported only there. For something new, babel is the safer bet.
  • Japanese, Chinese or Korean → the dedicated routes (the Japanese typesetting pages and the CJK page).