TikZ is the drawing language that lives inside LaTeX, and its name is a warning. It is a recursive acronym for the German TikZ ist kein Zeichenprogramm — “TikZ is not a drawing program” — telling you up front that you will not be dragging shapes with a mouse. Instead you write \draw (0,0) -- (2,1); in the same file as your prose, and the figure comes out set in the same fonts, at the same quality, as the paragraph around it. That is the bargain: you give up convenience and get precision and reproducibility. This page follows it from a first shape through coordinates and nodes to why compilation gets slow and what to do about it.
Why TikZ insists it is “not a drawing program” — TikZ and PGF
The name is a joke in the GNU tradition, and the manual says so itself: TikZ is a recursive acronym in the line of “gnu’s Not Unix,” put there to caution readers about what to expect. What you get in exchange for the mouse is the TeX approach applied to pictures — exact placement, reuse through macros, lettering that matches the surrounding text. What you hand over is WYSIWYG. The manual is candid about the rest of the bill too, listing the steep learning curve and the recompile that follows every small change within its first few pages.
Underneath, the thing that actually draws the lines is PGF, short for “portable graphics format,” and the name has a clear origin. Its author set out to write graphics macros that would work equally with pdfLaTeX and with the classic PostScript-based LaTeX; that required a layer to absorb the differences between output routes — hence portable. Because raw PGF is laborious to write, TikZ was laid on top of it as a syntax humans can read and type. People say “PGF/TikZ” as one word, but what you actually type is nearly always the TikZ side, and \usepackage{tikz} pulls PGF in with it.
Both were written by Till Tantau. He started messing about with TeX as an undergraduate, which produced the beamer presentation class, and later wrote TikZ for the graphics in his PhD thesis — his own account of it. The standard way to make LaTeX slides and the standard way to draw in LaTeX, two things that look unrelated, came from the same person. One number shows how far it has grown from a thesis helper: the manual for version 3.1.10, pgfmanual.pdf, runs to 1,321 pages. Its cover is itself a TikZ picture — fractal trees and Koch snowflakes over a dusk landscape — printed alongside the source code that generates it.
There is almost nothing to configure. One line, \usepackage{tikz}, in the preamble is enough for pdfLaTeX, LuaLaTeX, and XeLaTeX. The only route that needs extra care is the one through DVI: with pLaTeX or upLaTeX you also name the driver — usually dvipdfmx — as a class option. Here is a minimal document that compiles.
\documentclass{article} % with pLaTeX: \documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
A line and a circle:
\begin{tikzpicture}
\draw (0,0) -- (2,1);
\draw (2.8,0.5) circle [radius=0.5cm];
\end{tikzpicture}
\end{document}Drawing a first shape: the tikzpicture environment and the semicolon
Every figure goes inside \begin{tikzpicture} … \end{tikzpicture}, and every drawing command ends with a semicolon ;. The environment is the sheet that one picture is drawn on, and options in the brackets after the environment name apply to the whole sheet — [scale=2] doubles it, [thick] makes every line heavier. For a picture small enough to fit on one line you need not open the environment at all: there are the inline forms \tikz{...} and, for a single command, \tikz \draw ...;.
% inline: one command, no environment
\tikz \draw (0,0) -- (1.5,0);
% environment: one canvas, several commands, shared options
\begin{tikzpicture}[scale=1.2, thick]
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\end{tikzpicture}Drop one semicolon and you get ! Package tikz Error: Giving up on this path. Did you forget a semicolon?. The awkward part is that the reported line number is not the line you broke but the one after it. TikZ keeps swallowing tokens for as long as they could still belong to the path, and only gives up when it meets something that cannot — usually the next \draw. So when the error points at a \draw, the place to look is the end of the line above it.
Coordinates and paths: \draw, \fill, --, and circle
Drawing in TikZ revolves around the path — a route saying how you move from point to point — and the command name decides how that route is shown. \draw strokes it, \fill fills the inside of a closed one, \filldraw fills and then strokes the outline, and \path defines the route while drawing nothing at all. That last one sounds useless, but it is how you quietly place coordinates and nodes for later reference. Write the same list of points and swap only the command name, and an outline becomes a solid: that orthogonality is the backbone of the design.
There are three ways to write a point. Cartesian (x,y) defaults to centimeters, so (1,2) is 1 cm right and 2 cm up, and you may give units explicitly as in (1cm,2pt). Polar (30:1cm) reads “1 cm in the direction of 30°.” And a named coordinate, placed once with \coordinate (P) at (1,1);, is thereafter just (P). The difference between relative + and ++ is worth learning before it bites: ++(1,0) steps 1 cm right and moves the current point with it, while +(1,0) reaches the same place but leaves the current point where it was. Chain several ++ and you get a polyline; chain several + and you get spokes radiating from one anchor.
How the route proceeds is decided by path operations. -- is a straight line from the previous point to the next; rectangle takes two opposite corners; circle takes a center; then ellipse, arc, and grid. Curves come from .. controls .. (Bézier) or to[bend left], and a shape is closed by ending with -- cycle, which returns to the start. Shape arguments are now written as key–value pairs in brackets: circle [radius=10pt], ellipse [x radius=20pt, y radius=10pt], arc [start angle=0, end angle=30, radius=3mm], grid [step=.5cm]. The older parenthesis form circle (10pt) still works, but new code reads better in brackets, and adding one more key costs nothing.
\begin{tikzpicture}
\draw[step=.5cm, gray, very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (0,0) circle [radius=1cm];
\draw (0,0) -- (30:1cm); % polar: 1 cm at 30 degrees
\fill[blue!20] (0,0) rectangle (0.5,0.5);
\draw[red] (-1.2,-1.2) -- ++(0.6,0) -- ++(0,0.6); % ++ carries the current point
\end{tikzpicture}What comes out is a single picture: a faint gray grid in 0.5 cm steps; a circle of radius 1 cm about the origin; a short segment leaving the origin at 30°; a 0.5 cm square at the origin filled pale blue; and a red elbow at the lower left that goes 0.6 cm right, then 0.6 cm up. The color blue!20 means “20% blue,” the other 80% being white — hence pale. Name two colors, as in red!50!black, and you mix them; the notation works the same for fills and for strokes.
Nodes: placing text and boxes, then joining them by name
A node places text or a box at a coordinate, and the form is \node[options] (name) at (coordinate) {contents};. Options go in the brackets: draw for a border, circle or rectangle for the shape, fill=blue!20 for a fill, and so on. The point of the whole construction is that the name in parentheses becomes a handle on that node. From then on (name) refers to its position, and adding an anchor — (name.north), (name.east) — names a single point on its border.
From here comes the pattern you will use constantly: place named nodes first, then connect the names. Joining by node name instead of raw coordinates means the connecting line follows on its own when you nudge a node a centimeter later. And because the line stops at the node’s border, it never pokes into the circle or box. Nodes can also sit along a path: \draw (a) -- (b) node[midway, above] {$f$}; puts a label just above the midpoint of the line — the standard way to name an arrow.
\begin{tikzpicture}
\node (a) at (0,0) [draw, circle, fill=blue!20] {A};
\node (b) at (2.5,0) [draw, circle, fill=blue!20] {B};
\draw[->] (a) -- (b) node[midway, above] {$f$};
\draw[dashed] (a.south) -- (b.south); % .south is an anchor on the border
\end{tikzpicture}The picture puts two pale-blue circular nodes labeled “A” and “B” 2.5 cm apart, draws an arrow from A to B with $f$ sitting above its midpoint, and joins the bottoms of the two circles with a dashed line. There is one landmine here worth stepping around: a node must be defined before it is referenced. Name one you have not placed yet, or misspell one you have, and you get ! Package pgf Error: No shape named ‘b’ is known. Names are easy to mistype, so when that appears, check the spelling and check that the \node really comes earlier in the picture.
Line options and reusable styles with \tikzset
How a line looks is settled by options in brackets: the weights thin / thick / very thick, colors such as red or blue!50, dashed and dotted, rounded corners, and the arrows -> (tip at the end), <- (at the start), <-> (both). There is a pragmatic shortcut behind the arrows: TikZ treats any otherwise unknown option containing a - as an arrow specification. So a mistyped key has two possible fates, depending on its spelling. Without a -, TikZ tells you: ! Package pgfkeys Error: I do not know the key ‘/tikz/thikc’ and I am going to ignore it. Perhaps you misspelled it. With a - in it, the typo is read as an arrow spec instead and can fail silently into something odd.
| Option | Meaning |
|---|---|
thick / very thick | Heavier lines (up to ultra thick) |
red, fill=blue!50 | Stroke or fill color; !n sets intensity, red!50!black mixes two |
dashed / dotted | Dashed or dotted lines |
rounded corners | Round the corners of a path |
->, <-, <-> | Arrow tip at the end, the start, or both |
scale=2 | Scale that picture (or path) by 2 |
node distance=1cm | Default gap for relative placement with positioning |
Write the same decoration three times and that is the signal to make it a style. Define it in the preamble with \tikzset{name/.style={...}} and from then on you pass a single name; when the look has to change, one line in the definition changes all of it. If it only matters inside one picture, define it on the spot in the tikzpicture options instead. There are also styles that apply to every element of a kind — every node/.style={...} — and they are indispensable whenever a figure like a flowchart needs all its nodes to match.
\tikzset{help lines/.style={color=blue!50, very thin}}
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\draw[thick, red, ->, rounded corners] (0,0) -- (1,2) -- (3,2);
\end{tikzpicture}This draws a faint blue grid from (0,0) to (3,2), then a thick red line bending from the origin to (1,2) and on to (3,2), with rounded corners and an arrow tip at the end. Because the grid goes through a style, rewriting very thin as thin changes not just this grid but every grid drawn with help lines.
Which \usetikzlibrary you actually need
TikZ’s core is deliberately small; the specialized parts are split out into libraries, loaded from the preamble with \usetikzlibrary{...} — comma-separated if several. Until you load one, its convenient syntax simply does not exist: write right=of a without positioning and you land straight in the “I do not know the key” error from the previous section. These are the ones that actually earn their place in the first year.
arrows.meta— a rich, tunable set of arrow tips (-{Stealth},-{Latex}, …). The manual marks the olderarrowsandarrows.spacedas deprecated, so new code should use this one.positioning— relative node placement:right=of a,below=1cm of b, withnode distancesetting the default gap.calc— coordinate arithmetic:($(a)+(1,0)$)is “1 cm right of a,” and($(a)!0.5!(b)$)is “the midpoint of a and b.”shapes— node shapes beyond circle and rectangle (diamonds, stars, callouts), subdivided into parts such asshapes.geometric.decorations— decorate a path as a wave, zigzag, brace and more (decorations.pathmorphingand friends).patterns— fill with a pattern such as hatching, lines, or dots.fit— automatically build a box that exactly encloses several nodes; handy for grouping parts of a figure.backgrounds— draw a frame or backdrop on a layer behind the picture, so it never collides with the foreground.matrix— align nodes in a grid (a matrix).graphdrawingdoes automatic layout instead, but it requires LuaTeX.
Just arrows.meta plus positioning is enough for a usable flowchart. The trick is to give a coordinate to the first node only and place the rest by relation — “right of that one,” “below that one.” Insert a node later and there are no coordinates to renumber.
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning}
\begin{tikzpicture}[node distance=1cm, every node/.style={draw, rounded corners}]
\node (start) {Start};
\node (proc) [right=of start] {Process};
\node (end) [right=of proc] {End};
\draw[-{Stealth}] (start) -- (proc);
\draw[-{Stealth}] (proc) -- (end);
\end{tikzpicture}The result is a left-to-right flowchart: three rounded boxes reading “Start,” “Process,” and “End,” 1 cm apart, joined in order by sharp Stealth tips. every node/.style settles the look of all three at once, and node distance=1cm settles the gap that right=of uses. Putting both in the picture options is what makes a figure easy to revise later.
Why TikZ compilation is slow, and when to use external or standalone
It is slow because TeX itself does the arithmetic, in macros. Adding coordinates, turning an angle into a point, subdividing a Bézier curve — all of it runs inside the typesetting pass rather than in some external engine. And nothing is cached, so every single \draw is computed again from scratch on every compilation. With a handful of figures you never notice; stack up dense grids, plots with many points, and pictures holding dozens of nodes, and the wait becomes obvious. The manual itself admits this early on, listing long recompiles after small changes as part of the price of the TeX approach.
The standard remedy is the external library. Load \usetikzlibrary{external}, declare \tikzexternalize, and each tikzpicture is written out once to its own PDF and cached. Names are assigned automatically: from main.tex you get main-figure0, main-figure1, and so on. On later runs, if a picture’s source is unchanged, the computation is skipped entirely and the finished PDF is simply included; change the picture and it is rebuilt. The default mode=convert with system call has LaTeX invoke itself to produce the images, so it must be run with -shell-escape (pdflatex -shell-escape main). Forget that flag and no figures are generated — check it first when nothing appears.
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize % caches each picture as main-figure0.pdf, main-figure1.pdf, ...
% compile with: pdflatex -shell-escape mainThe other road is the standalone class. Move the figure into its own .tex, compile it alone with \documentclass[tikz]{standalone}, and the tikz option loads the tikz package and produces a one-page PDF cropped to the picture’s natural size (several tikzpictures give several pages). The main document then just says \includegraphics{figure}. The rule of thumb: use external when the figure grows alongside the text — the code stays next to the prose and you gain only the cache. Use standalone when the figure is shared with other documents or slides, or when you are going to iterate on it dozens of times — a small document that compiles in seconds is the faster place to experiment.
% compiles on its own to a one-page PDF, cropped to the picture
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}
\draw[-{Stealth}, thick] (0,0) -- (2,1);
\end{tikzpicture}
\end{document}
% then in the main document: \includegraphics{figure}