DEV Community

Write Chemical Structural Formulas Faster in LaTeX with KKchemstruct

Hi, I'm KKTeX. I build LaTeX tools for teaching materials.

If you typeset chemical structural formulas in LaTeX, chemfig is the standard choice. It is flexible enough to draw everything from benzene rings to reaction schemes, but repeating the same structures across a worksheet means repeatedly matching bond lengths, line widths, and double-bond spacing.

I made KKchemstruct to package those recurring settings and structures into short commands:

\KKbenzene[2=OH,3=COOH]                     % salicylic acid
\KKchemchain{H-O-S(\KKdative{2}O)(\KKdative{6}O)-O-H}
\KKscheme{\KKsalicylicacid\arrow{->[\ck{CH_3OH}][Esterification]}\KKmethylsalicylate}
Enter fullscreen mode Exit fullscreen mode

This article focuses on using the package rather than its implementation.

Basic examples made with KKchemstruct

What it does

  • Draw substituted benzene rings by numbered positions
  • Keep bond lengths and line widths consistent in condensed structural formulas
  • Assemble reaction schemes, branching reactions, and compound names
  • Add leaving-group marks, hydrogen bonds, and a cross for “no reaction”
  • Insert common compounds with a single command
  • Scale dimensions with the surrounding text by using em-based settings

The actual drawing is still handled by chemfig. When a prepared command is not enough, you can use ordinary chemfig syntax directly.

1. Install it

You need LuaLaTeX (recommended), or pLaTeX with dvipdfmx. The dependencies—chemfig, etoolbox, and xkeyval—are included in TeX Live.

Download KKchemstruct.sty from the GitHub repository and, for the simplest setup, put it next to your .tex file:

my-document/
├── main.tex
└── KKchemstruct.sty
Enter fullscreen mode Exit fullscreen mode

Then add one line to the preamble:

\usepackage{KKchemstruct}
Enter fullscreen mode Exit fullscreen mode

Here is a minimal example:

\documentclass[a4paper,11pt]{article}
\usepackage[margin=22mm]{geometry}
\usepackage{KKchemstruct}

\begin{document}

\begin{center}
  \KKname{\KKsalicylicacid}{Salicylic acid}
\end{center}

\end{document}
Enter fullscreen mode Exit fullscreen mode

Compile it as usual:

lualatex -interaction=nonstopmode -halt-on-error main.tex
Enter fullscreen mode Exit fullscreen mode

Documents using \KKchemmark or \KKhbond need two runs so that TikZ can resolve the node positions.

2. Draw substituted benzene rings by number

Use \KKbenzene and assign substituents to numbered positions:

\KKbenzene[2=OH,3=COOH]
Enter fullscreen mode Exit fullscreen mode

Position 1 is at the top, and the numbers continue clockwise:

           1
       6       2
       5       3
           4
Enter fullscreen mode Exit fullscreen mode

These three commands draw salicylic acid, terephthalic acid, and unsubstituted benzene:

\KKbenzene[2=OH,3=COOH]
\KKbenzene[1=COOH,4=COOH]
\KKbenzene[]
Enter fullscreen mode Exit fullscreen mode

Substituted benzene rings and a condensed structural formula

Subscripts such as COOCH_3 work directly:

\KKbenzene[2=OH,3=COOCH_3]
Enter fullscreen mode Exit fullscreen mode

Use angle to rotate a ring and sep to change the side length for that ring only:

\KKbenzene[2=OH,angle=30,sep=1.0em]
Enter fullscreen mode Exit fullscreen mode

If a substituent comes too close to an inner double bond, reverse the Kekulé pattern with kekule=b:

\KKbenzene[1=OH,kekule=b]
Enter fullscreen mode Exit fullscreen mode

For a horizontally connected ring inside a line of text, use one of these commands:

Command Purpose
\KKphenylring An unsubstituted ring
\KKphenyl{COOH} A substituent on the right
\KKphenylene{SO_3H} Bonds on both sides, for inserting the ring into a chain

Their baselines are adjusted so that they do not excessively increase the line spacing.

3. Write condensed structural formulas

Pass chains of atom labels to \KKchemchain:

\KKchemchain{CH_2(-OH)-[6,1.15]CH(-OH)-[6,1.15]CH_2-OH}
Enter fullscreen mode Exit fullscreen mode

The angle numbers follow chemfig's 45-degree system. These four cover many classroom formulas:

Value Direction
[0] right
[2] up
[4] left
[6] down

The number after the angle is a length multiplier, so [6,1.15] means downward at 1.15 times the default length.

Common fragments have shorter commands:

\KKchemchain{R_1-C\KKcarbonyl-OH}
\KKchemchain{H-O-S(\KKdative{2}O)(\KKdative{6}O)-O-H}
Enter fullscreen mode Exit fullscreen mode
Command Result
\KKcarbonyl Upward C=O
\KKcarbonyldown Downward C=O
\KKdative{angle} A coordinate bond such as S→O, P→O, or N→O

Rings and chains have separate commands because they need different spacing rules:

  • \KKbenzene and \KKchemring keep atom-center distances constant to preserve regular polygons.
  • \KKchemchain keeps the visible bond lines consistent, even after a wide label such as CH_2.

Choosing the appropriate command is often enough to make a page of formulas look much more uniform.

4. Insert common compounds with one command

Frequently used compounds already have named commands:

\KKsalicylicacid
\KKmethylsalicylate
\KKaspirin
\KKphthalicanhydride
\KKmaleicacid
\KKfumaricacid
\KKnitricacid
\KKsulfuricacid
\KKphosphoricacid
\KKglycerol
\KKtriglyceride{R_1}{R_2}{R_3}
Enter fullscreen mode Exit fullscreen mode

Benzoic acid, phenol, all three phthalic-acid isomers, maleic anhydride, and more are also included. See the English manual for the full list.

Use \KKname to place a name below a structure:

\KKname{\KKaspirin}{Acetylsalicylic acid}
Enter fullscreen mode Exit fullscreen mode

5. Build reaction schemes

Inside \KKscheme, arrange structures with chemfig's \arrow command:

\KKscheme{%
  \KKname{\KKsalicylicacid}{Salicylic acid}
  \arrow{->[\ck{CH_3OH}][Esterification]}
  \KKname{\KKmethylsalicylate}{Methyl salicylate}}
Enter fullscreen mode Exit fullscreen mode

Linear and branching reaction schemes

Arrow labels are not in math mode. Wrap formulas such as CH_3OH in \ck{...}:

\arrow{->[\ck{CH_3OH}][Esterification]}
Enter fullscreen mode Exit fullscreen mode

The longer alias \KKchemformula{...} does the same thing.

For one substrate branching into two reactions, \KKbranchscheme takes seven arguments:

\KKbranchscheme
  {\KKname{\KKsalicylicacid}{Salicylic acid}}
  {\ck{CH_3OH}}{Esterification}
  {\KKname{\KKmethylsalicylate}{Methyl salicylate}}
  {\ck{(CH_3CO)_2O}}{Acetylation}
  {\KKname{\KKaspirin}{Acetylsalicylic acid}}
Enter fullscreen mode Exit fullscreen mode

The order is: substrate, upper reagent, upper reaction name, upper product, lower reagent, lower reaction name, lower product.

6. Add annotations

To outline a leaving group, mark two atoms with @{name} and pass the names to \KKchemmark:

\KKchemchain{R-C\KKcarbonyl-@{s}OH}\ +\
\KKchemchain{@{e}H-O-R'}%
\KKchemmark{s}{e}
Enter fullscreen mode Exit fullscreen mode

To draw an intramolecular hydrogen bond:

\KKbenzene[2=@{oh}OH,3=C@{co}OOH]%
\KKhbond{oh}{co}
Enter fullscreen mode Exit fullscreen mode

To place a cross over a structure:

\KKchemcross{\KKphenol}
Enter fullscreen mode Exit fullscreen mode

Leaving-group marks, a hydrogen bond, a cross, and size adjustments

Because \KKchemmark and \KKhbond refer to TikZ nodes, compile twice:

lualatex -interaction=nonstopmode -halt-on-error main.tex
lualatex -interaction=nonstopmode -halt-on-error main.tex
Enter fullscreen mode Exit fullscreen mode

7. Adjust bond lengths and line widths together

Change global dimensions with \KKchemsetup:

\KKchemsetup{
  ring sep=2.0em,
  bond width=0.09em,
  double bond sep=0.4em
}
Enter fullscreen mode Exit fullscreen mode

Put the setup in a group when you want a local change:

\begingroup
  \KKchemsetup{ring sep=2.0em,bond width=0.09em}
  \KKsalicylicacid
\endgroup

% Back to the defaults here
\KKsalicylicacid
Enter fullscreen mode Exit fullscreen mode

The dimensions are primarily expressed in em, so the structures follow surrounding size changes such as \small and \large.

8. Draw rings that do not have a prepared command

For fused rings and other special cases, pass raw chemfig syntax to \KKchemring:

\KKchemring[atom sep=1.75em]{%
  *6(=-*5(-C(=O)-O-C(=O)-)=-=-)}
Enter fullscreen mode Exit fullscreen mode

KKchemstruct is not meant to hide chemfig. Its purpose is to standardize common settings and components: use short commands for repeated structures, and drop down to chemfig syntax only for the unusual parts.

Common pitfalls

Parentheses create branches

In chemfig, ( and ) are structural branch syntax. If you only want to display a molecular formula such as CH_3(CH_2)_{11}, use \ck{...} rather than passing it directly to \KKchemchain.

Wrap formulas in arrow labels with \ck

Unlike atom labels in a structure, reaction-arrow labels are not automatically typeset in math mode:

\arrow{->[\ck{H_2SO_4}][Heat]}
Enter fullscreen mode Exit fullscreen mode

Compile annotations twice

The positions used by \KKchemmark and \KKhbond are not final on the first run. If an annotation is displaced even though compilation succeeds, run LaTeX again.

Use the ring and chain commands for their intended geometry

Use \KKbenzene or \KKchemring when a regular polygon matters, and \KKchemchain for a condensed structural formula. Some inputs compile with either command, but the spacing will differ.

License and dependencies

KKchemstruct is released under the MIT License. It uses the LPPL 1.3c-licensed chemfig for drawing, plus the LPPL-licensed etoolbox and xkeyval packages. These dependencies are loaded from your TeX installation; their code is not copied into KKchemstruct.

Start with four commands

KKchemstruct keeps chemfig's flexibility while making repeated classroom structures shorter and more consistent. These four commands are enough to get started:

\KKbenzene[2=OH,3=COOH]  % substituted benzene
\KKchemchain{...}        % condensed structural formula
\KKscheme{...}           % reaction scheme
\KKchemsetup{...}        % dimensions
Enter fullscreen mode Exit fullscreen mode

When you need a structure that is not predefined, use chemfig syntax through \KKchemring or \KKchemchain. If the same structure keeps appearing, that is the right time to turn it into your own command.

Top comments (0)