The first decision when setting chemical formulae in LaTeX is not how to write them but which package to load. mhchem's \ce{H2O} and chemmacros's \ch{H2O} both produce the same H₂O — but loading the two together the obvious way fails with ! LaTeX Error: Option clash for package mhchem., in either order. This page works through how \ce{} handles reactions, charges, states and isotopes, how IUPAC nomenclature is typeset, and what changed when chemmacros threw away its module mechanism at version 6 — all compiled on TeX Live 2024. The notation for drawing structures themselves (bond symbols, angles, rings) belongs to the chemistry-and-physics figures page; here the concern is fitting chemistry into a document.
Using mhchem: with \ce{}, typing it naturally is correct
Load \usepackage{mhchem} and put everything chemical inside \ce{...}. The design principle is consistent: type it the way you would write it on paper and the typesetting comes out right. A digit straight after an element symbol drops to a subscript (\ce{H2O} gives H₂O), a number and sign after ^ become a charge superscript (\ce{SO4^2-} gives SO₄²⁻), -> becomes a reaction arrow and <=> an equilibrium arrow. The parenthesised state symbols (aq), (s), (l) and (g) pass through as written, a trailing v becomes the downward arrow of a precipitate and ^ the upward arrow of an evolved gas. The version in TeX Live 2024 is v4.10, dated 29 January 2024, by Martin Hensel.
\usepackage{mhchem}
% ...
\ce{2 H2 + O2 -> 2 H2O} % a balanced reaction
\ce{SO4^2-} % ion with charge
\ce{CO2 + C <=> 2 CO} % equilibrium
\ce{NaCl(aq) + AgNO3(aq) -> AgCl(s) v + NaNO3(aq)} % states, precipitate
\ce{CaCO3 ->[$\Delta$] CaO + CO2 ^} % labelled arrow, gas evolved
\ce{^{227}_{90}Th+} % isotope with mass and atomic number
\ce{CuSO4.5H2O} % the dot becomes a centred dot
\ce{H+ + OH- <=>> H2O} % unequal equilibriumEvery line above was compiled on TeX Live 2024 and checked with pdftotext. Arrows take labels in square brackets, and writing ->[above][below] puts separate conditions on each side. Isotopes go as \ce{^{227}_{90}Th+}, with mass number and atomic number stacked before the symbol, and the interpunct of a hydrate comes straight from the period in \ce{CuSO4.5H2O}. Besides <=> there are <=>> and <<=> for equilibria lying to one side. \ce{} behaves identically in running text and inside $...$, so it drops into the middle of a paragraph without ceremony.
| What you type | What you get | The idea |
|---|---|---|
H2O | H₂O | A digit right after an element symbol becomes a subscript |
SO4^2- | SO₄²⁻ | Number and sign after ^ become a charge superscript |
2 H2 + O2 -> 2 H2O | A reaction with coefficients and an arrow | Coefficients go in front, separated by a space; -> is the arrow |
CO2 + C <=> 2 CO | An equilibrium arrow | <=> is balanced; <=>> and <<=> lean to one side |
AgCl(s) v | AgCl(s)↓ | State symbols pass through as written; a trailing v is the precipitate arrow |
CaCO3 ->[$\Delta$] CaO | A Δ sits above the arrow | ->[above][below] writes conditions on both sides of the arrow |
CuSO4.5H2O | CuSO₄·5H₂O | The period of a hydrate becomes a centred dot |
A small aside: open mhchem.sty and the maintainer's contact details sit in the opening comments encrypted with ROT13, with the reason given — to fight spam — and a note telling you to search the internet if you do not know ROT13. It is the most human corner of a package that has been maintained for over twenty years. The implementation is thoroughly modern underneath: it pulls in expl3, l3keys2e, calc, amsmath, chemgreek and graphics on its own. amsmath is loaded by mhchem for you, so you need not write it yourself.
When you see Option clash for package mhchem
Putting both mhchem and chemmacros in \usepackage lines stops the run with ! LaTeX Error: Option clash for package mhchem. Both orders were tried on TeX Live 2024 and both failed identically. The cause is that chemmacros picks a formula engine internally and, in doing so, loads mhchem itself with its own options. The fix is to write \usepackage[formula=mhchem]{chemmacros} — that alone removes the clash and makes chemmacros's \ch{...} run on mhchem underneath. In a test, \ch{2 H2 + O2 -> 2 H2O} and \iupac{ethanol} compiled in the same document without an error.
% WRONG -- fails with "! LaTeX Error: Option clash for package mhchem."
% \usepackage{chemmacros}
% \usepackage{mhchem}
% RIGHT -- let chemmacros load mhchem itself
\usepackage[formula=mhchem]{chemmacros}
% ...
\ch{2 H2 + O2 -> 2 H2O}
\iupac{ethanol}While you are here, two messages that chemmacros emits when loaded bare are worth recognising. The first is Package chemmacros Warning: You haven't loaded any package for upright Greek, meaning no upright-Greek mechanism has been selected through chemgreek — relevant as soon as you write the α of an α-amino acid. The second is the info line beginning Package chemmacros Info: You haven't chosen a formula method so I'm assuming, which is exactly the formula= key above. Neither is an error, but if your formulae do not look the way you expected, these two lines are the first place to look.
chemmacros v6: the modules are gone
Any description of chemmacros as a bundle whose modules you load one by one is out of date. The version in TeX Live 2024 is v6.2a, dated 11 March 2022, by Clemens Niederberger, and the package says so itself: the module mechanism changed at v6, all modules have been folded into the main package and are preloaded already unless you loaded chemmacros with the minimal option, and the new default corresponds to the old modules=all. Writing \usechemmodule now produces only that warning and does nothing. In other words, the single line \usepackage{chemmacros} already gives you nomenclature, oxidation numbers, Newman projections and the rest. The default formula engine is chemformula, a separate package whose \ch{...} resembles mhchem's, and chemformula can also be loaded on its own as \usepackage{chemformula}.
There is proper relief for anyone recompiling an old manuscript. The head of chemmacros.sty carries \DeclareRelease {v4} {2015-02-08} and \DeclareRelease {v5} {2020-03-07}, and TeX Live really does ship chemmacros-2015-02-08.sty and chemmacros-2020-03-07.sty alongside it. LaTeX's rollback mechanism lets you name an older release by date, so if a paper written in the v5 era breaks under v6, pin the old version and compare before you start rewriting.
Setting IUPAC names: \iupac and italic stereodescriptors
The name of an organic compound resembles a formula in that its appearance is fixed by convention. \iupac{...} takes care of those conventions: inside it, \- is a hyphen that may break across lines, and \higher{...} places a stereodescriptor raised and italic. Writing \iupac{(1\higher{R},3\higher{S})\-camphor} sets (1R,3S)-camphor with the R and S italicised. Because the locant hyphens double as break points, long names are far less likely to run out of a column in a two-column paper.
\usepackage[formula=mhchem]{chemmacros}
\usepackage{ghsystem} % needed separately for \ghspic and the H/P statements
% ...
\iupac{2,4,6\-trinitrotoluene} % \- is a breakable hyphen
\iupac{(1\higher{R},3\higher{S})\-camphor} % italic stereodescriptors
\ox{2,Ca} \ox{-2,O} % oxidation numbers, roman
\cip{R,S} % Cahn-Ingold-Prelog descriptors
\latin{in situ} % Latin phrases, per house style
\pH{} \pKa{} \pOH{} % upright p, italic quantity
\newman{0,60,120,180,240,300} % a Newman projectionEvery command above ran on TeX Live 2024. \ox{2,Ca} puts a roman-numeral oxidation state on Ca's shoulder and \ox{-2,O} handles negative states. \cip{R,S} sets Cahn–Ingold–Prelog descriptors, \latin{in situ} sets Latin phrases to house style, and \pH, \pKa and \pOH give the standard upright p with an italic quantity symbol. \newman{...} takes a list of angles and draws a Newman projection. One thing does need care: the GHS hazard pictograms. \ghspic{skull} fails with ! Undefined control sequence. under chemmacros alone — add \usepackage{ghsystem} separately.
Structures and reaction schemes: \chemname and the arrow-label trap
The structures themselves are drawn by chemfig — its notation of -, = and ~ bonds, angles 0 to 7, and rings such as *6(...) is covered on the chemistry-and-physics figures page. What concerns us here is the layer that puts them into a document. \schemestart ... \schemestop builds a reaction scheme: lay out the molecules and separate them with \arrow. Each molecule can carry a name via \chemname{\chemfig{...}}{benzene}, set neatly beneath the structure. Overall scale and bond weight are set together with something like \setchemfig{atom sep=2em, bond style={line width=1pt}}. The version in TeX Live 2024 is v1.66, dated 28 December 2023, by Christian Tellechea.
\usepackage{mhchem}
\usepackage{chemfig}
\setchemfig{atom sep=2em, bond style={line width=1pt}}
% ...
\schemestart
\chemname{\chemfig{*6(-=-=-=)}}{benzene}
% arrow labels are ordinary TEXT: bare "FeBr_3" gives "! Missing $ inserted."
\arrow{->[\ce{Br2}][\ce{FeBr3}]}
\chemname{\chemfig{*6(-=-(-Br)=-=)}}{bromobenzene}
\schemestopThe arrow labels hold a trap worth measuring. What goes inside the brackets of \arrow{->[...]} is ordinary text, not math. So \arrow{->[FeBr_3]} puts an _ into running text, and the run cascades from ! Missing $ inserted. through ! Extra }, or forgotten $. and ! Undefined control sequence. until it complains that \node is undefined and the figure is wrecked. Wrap a label that needs subscripts in \ce{FeBr3} or \chemfig{FeBr_3}. Using \ce{} and chemfig in one document is the recommended pairing — a different matter from the chemmacros clash above — and loading both went through cleanly here. Beyond that, \charge adds lone pairs and charges, \chemabove and \chembelow annotate above and below an atom, and \polymerdelim draws the brackets of a repeating unit.
So which packages do you actually load
If all you need is formulae and equations, load mhchem alone. That is the right answer for the overwhelming majority of papers, and \ce{} is the only command to learn. If you also draw structures, use mhchem plus chemfig — the two do not conflict, and the standard arrangement is \ce{} for the equations in the prose and \chemfig{} for the displayed skeletons. If you go as far as nomenclature, oxidation numbers, GHS and thermodynamics, reach for chemmacros, but pass it [formula=mhchem] rather than loading mhchem on its own line. Add packages in that order, only as far as you need, and you will meet neither Option clash nor Undefined control sequence.