Commutative diagrams (tikz-cd / amscd)

A commutative diagram lays out objects as points and the maps between them as arrows, so that “every path of composites agrees” can be seen at a glance. LaTeX offers two main tools for setting them: the powerful **tikz-cd, built on top of TikZ, and the simpler AMS package amscd**. This page sets a commutative square — the most basic such diagram — in each of them, sorts out how to give arrows their direction, labels, and line style, and compares when to reach for which.

What a commutative diagram is

Commutative diagrams are used throughout algebra, category theory, and topology to convey relationships at a glance. The smallest example is the commutative square: objects A, B, C, D at the four corners, with a map f along the top (A to B), g along the bottom (C to D), a map down the left (A to C), and a map down the right (B to D). To say “the square commutes” is simply to claim that the two paths from A to D — across the top then down the right, versus down the left then across the bottom — are the same map.

A diagram is itself a piece of mathematics, so you normally place it inside a display math environment (\[\] or the equation environment). Historically many packages were written for the job (xy/xypic, diagrams, and others), but today the de facto standard is **tikz-cd, which draws curves, diagonal arrows, and intricate multi-row diagrams with ease. When a plain rectangular diagram is enough, however, the AMS package amscd** is the lightweight choice. We take them in turn below.

tikz-cd — the modern choice

tikz-cd adapts the general-purpose drawing package TikZ for commutative diagrams. Load it in the preamble with \usepackage{tikz-cd} (or, having loaded TikZ, with \usetikzlibrary{cd}), and you get the tikzcd environment. Its contents are written as a matrix, just like LaTeX’s tabular: cells are separated by & and rows by \\. Each cell is a node where you place an “object,” and everything is set in math mode automatically.

Arrows between objects are drawn with the **\arrow command; the short alias \ar** does exactly the same thing. In the cell where the arrow starts, you write \arrow[…] and specify its target and decoration inside the brackets. The target is given with direction keys: r for right, l for left, u for up, d for down. These combine as a string — for example [rd] points to the cell one step right and one step down (a diagonal).

To put a label (the name of a map) on an arrow, write a quoted string among the options. \arrow[r, "f"] is “an arrow to the cell on the right, labelled f.” By default the label sits on the left of the arrow (relative to its direction); putting an **apostrophe '** immediately after the quoted label moves it to the opposite side (written as "g"'). A single arrow may carry several labels, and you can fine-tune their position, as in "f" near start. Here is a short example showing the typical usage.

latex
\[
\begin{tikzcd}
  A \arrow[r, "\phi"] \arrow[rd] & B \\
  & C
\end{tikzcd}
\]

This produces A at top left, B at top right, and C at bottom right: a horizontal arrow runs from A to B on the right carrying the label φ, while a diagonal arrow simultaneously drops from A to C at the lower right. Note that \arrow[r, "\phi"] and \arrow[rd] are written one after another in the same cell A — a single cell can emit any number of arrows.

With that in hand, let us set the commutative square described at the outset. Place the four corners A, B, C, D as a 2×2 matrix, and draw four arrows: f from A to the right, a left side from A downward, a right side from B downward, and g from C to the right.

latex
\[
\begin{tikzcd}
  A \arrow[r, "f"] \arrow[d, "\alpha"] & B \arrow[d, "\beta"] \\
  C \arrow[r, "g"]                      & D
\end{tikzcd}
\]

This gives a square with A, B, C, D at the corners: f pointing right along the top, g pointing right along the bottom, α pointing down the left side, and β pointing down the right side. Each label sits on its default side (left of the arrow’s direction). To push the right-hand β to the other (outer) side, for instance, write \arrow[d, "\beta"']. Since the inside of tikzcd is math mode, use \text{…} (from amsmath) within the label option when you want ordinary words in a label.

The great strength of tikz-cd is how finely you can change an arrow’s appearance. Line style, arrowhead, and curvature are switched simply by adding style keys to the \arrow options. The table below collects the common ones. Several may be given at once (as in \arrow[r, tail, two heads, dashed]) and combined freely.

KeyEffect
hookA hook (⊂) at the tail, for an inclusion or injection
two headsA doubled arrowhead, for a surjection
tailAdds a tail at the start (another mark for an injection)
dashedMakes the line dashed (often a uniquely-determined map)
dottedMakes the line dotted (a TikZ key)
equalDraws a double line (an equality) instead of an arrow
bend leftBends the arrow in a left-hand arc (bend left=20 sets the angle)
bend rightBends the arrow in a right-hand arc

It is common to place an isomorphism mark such as \sim or \simeq on an arrow as a label. For instance \arrow[r, dashed, "\simeq"] sets the isomorphism sign ≃ over a dashed arrow. To draw two distinct arcs between the same pair of objects, use bend left and bend right. Because tikz-cd also accepts TikZ keys directly (color=…, dotted, in=…/out=…, and so on), its expressive range is effectively that of all of TikZ.

One caveat: tikzcd diagrams do not display correctly in DVI viewers. Compile with pdflatex, lualatex, or xelatex (which produce PDF directly), or through a DVI-to-PDF/PS route. Note too that \arrow has an older form predating the quotes syntax, \arrow[…]{direction}labels (e.g. \arrow{r}{f}), still available for backward compatibility — but for new work the quotes syntax is more readable and is recommended.

amscd — the AMS CD environment

amscd ports the commutative-diagram facility of AMS-TeX to LaTeX; load it in the preamble with \usepackage{amscd}. It provides a single **CD environment**. As with tikz-cd, you write the contents as a matrix using & and \\, but amscd depends on no external package (no TikZ) and runs on TeX’s typesetting alone, so it is lightweight. Its design is deliberately spare, however: it can draw only horizontal and vertical arrows (see below).

Every arrow is written as a special token beginning with **@**. Horizontal arrows are @>>> (rightward) and @<<< (leftward); vertical arrows are @VVV (downward — the V of “vertical”) and @AAA (upward — an A read as an upward-pointing arrow). The equality (double line) is @= horizontally and @| (or @\vert) vertically. For a lattice point that should carry no arrow at all, place @. (a dot). Horizontal arrows go between objects (at the & position on the same row); vertical arrows go on the row directly beneath their object.

Labels are written between the characters that make up an arrow. The horizontal @>>> has three > delimiters and thus two slots: text in the first slot (right after @>) goes above the arrow, text in the second slot goes below. So @>f>> puts f above, @>>g> puts g below, and @>f>g> puts f above and g below. The vertical @VVV works the same way: @VfVV puts f to the left of a downward arrow and @VVfV puts it to the right (the same rule holds for @AAA).

Here is the commutative-square example from the AMS amscd manual. It assumes \End has been defined as an operator name (like \operatorname).

latex
\[
\begin{CD}
  S^{{\mathcal{W}}_\Lambda}\otimes T  @>j>>  T \\
  @VVV                                @VV{\End P}V \\
  (S\otimes T)/I                     @=  (Z\otimes T)/J
\end{CD}
\]

In this diagram the top row runs a horizontal arrow from the left object to T on the right, with the label j set above it. The middle row (@VVV and @VV{\End P}V) makes the vertical arrows: an unlabelled downward arrow in the left column, and a downward arrow with the label End P on its right in the right column. The bottom row joins its two objects with @=, a double-line equality. The braces in {\End P} group a multi-token label into one unit.

Setting this page’s opening f/g/α/β commutative square in amscd looks like the following. The labels on the left- and right-side vertical arrows are placed in the first slot (the left side), as described above.

latex
\[
\begin{CD}
  A    @>f>>    B \\
  @VV\alpha V   @VV\beta V \\
  C    @>g>>    D
\end{CD}
\]

This yields a square with A, B, C, D at the corners: a rightward arrow f along the top, a rightward arrow g along the bottom, a downward arrow α on the left side, and a downward arrow β on the right side. It is exactly the same diagram as the tikz-cd example; only the @-spelling notation differs. Since amscd’s CD environment is math mode, you again place it inside display math (above we use \[\]).

Which to use

The two packages have clearly different scope. amscd’s CD environment handles only grid-like (rectangular) diagrams; the AMS manual itself states plainly that it supports “only simple rectangular diagrams, with no diagonal arrows or more exotic features.” That is its chief limitation. If you need diagonal arrows, curves, or intricate multi-row diagrams, amscd cannot draw them and you turn to tikz-cd (or the xy family).

  • Need diagonal arrows or curvestikz-cd. amscd is horizontal/vertical only and cannot slant.
  • Want fine control of arrowheads and line styles (injection hook, surjection two heads, dashed, double lines, …) → tikz-cd.
  • A plain rectangular diagram is enough / you want light dependenciesamscd. It loads no TikZ and is lightweight and fast.
  • Notation taste: amscd’s @>>> spelling is terse but idiosyncratic; tikz-cd’s \arrow[r, "f"] is verbose but plain to the reader.
  • Output route: tikz-cd does not display correctly in DVI viewers, so it presumes a PDF-producing engine (pdfLaTeX, etc.); amscd has no such constraint.

A rule of thumb: if your paper has the occasional rectangular diagram, amscd is plenty — no extra dependency and quick to set. If diagrams are central and you lean on slanted maps, curves, or elaborate arrowheads, choose tikz-cd. And keep in mind that for something as simple as “A → B,” you often need no diagram environment at all — an inline command such as \xrightarrow{f} (from amsmath) will do.