Code Listings in LaTeX: listings, minted and verbatim
Quick answer
- Code block with highlighting:
\usepackage{listings}, then\begin{lstlisting}[language=Python]…\end{lstlisting}. - Code from a file:
\lstinputlisting[language=Python]{script.py}. - Styling for every listing:
\lstset{basicstyle=\ttfamily\small, numbers=left, frame=single}in the preamble. - Better highlighting:
\usepackage{minted}and\begin{minted}{python}; needs Pygments and compiling with-shell-escape. - No package, no colors:
\begin{verbatim}…\end{verbatim}. - Inline code:
\verb|x = 1|or, with listings,\lstinline|x = 1|.
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\lstset{basicstyle=\ttfamily\small, numbers=left, frame=single,
keywordstyle=\color{blue}, commentstyle=\color{gray}}
\begin{document}
\begin{lstlisting}[language=Python]
def square(x):
# return the square of x
return x * x
\end{lstlisting}
Inline: \lstinline|square(3)| or \verb|square(3)|.
\end{document}Coding in LaTeX usually means showing code, not writing it: a program in a thesis appendix, a snippet in a paper, a command in a tutorial. LaTeX has three tools for this. The listings package highlights code with no outside help and works on every compiler; minted gives better highlighting through the Python library Pygments; and the built-in verbatim environment prints code exactly as typed with no colors at all. This guide covers all three, how to style a listing, include code from a file, add captions and line numbers, and fix the errors each one produces.
listings vs minted vs verbatim
listings | minted | verbatim | |
|---|---|---|---|
| Syntax highlighting | Keywords, comments, strings | Full, token-by-token (Pygments) | None |
| Languages | About 100 built in | 500+ | Any (no highlighting) |
| External program | No | Pygments (Python) | No |
Needs -shell-escape | No | Yes (see below) | No |
| Block environment | lstlisting | minted | verbatim |
| From a file | \lstinputlisting | \inputminted | \verbatiminput (verbatim package) |
| Inline | \lstinline | \mintinline | \verb |
| Line breaking | breaklines=true | breaklines | No |
If you are not sure, start with listings: it compiles anywhere, including online editors and journal submission systems where you cannot pass compiler flags.
LaTeX Listing with the listings Package
Load listings in the preamble and put the code between \begin{lstlisting} and \end{lstlisting}. Everything inside is printed as typed, including backslashes, braces and % signs, so you do not escape anything. The language option turns on keyword highlighting:
\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}[language=Python]
import math
def area(r):
"""Area of a circle with radius r."""
return math.pi * r**2 # %, \ and {} are fine
print(area(2))
\end{lstlisting}
\end{document}Without a style, keywords are only set in bold. The language names are case-insensitive; some need a dialect in square brackets. The most used ones:
| Language | Option |
|---|---|
| Python | language=Python |
| C / C++ | language=C, language=C++ |
| C# | language={[Sharp]C} |
| Java | language=Java |
| MATLAB | language=Matlab |
| R | language=R |
| SQL | language=SQL |
| Shell | language=bash |
| HTML / XML | language=HTML, language=XML |
| LaTeX | language={[LaTeX]TeX} |
| JavaScript, Rust, Go, Swift | Not built in: use \lstdefinelanguage or minted |
Captions, labels and a list of listings
Add caption and label as options. Listings are numbered separately from figures and tables, and \lstlistoflistings prints a list of them like a list of figures:
\documentclass{article}
\usepackage{listings}
\renewcommand{\lstlistingname}{Code} % "Listing 1" -> "Code 1"
\renewcommand{\lstlistlistingname}{List of Code}
\begin{document}
\lstlistoflistings
\begin{lstlisting}[language=C, caption={Hello world in C}, label={lst:hello}]
#include <stdio.h>
int main(void) { printf("Hello\n"); return 0; }
\end{lstlisting}
Code~\ref{lst:hello} prints a greeting.
\end{document}Including Code from a File with \lstinputlisting
For real programs, keep the source in its own file and include it, so the document always shows the current version. firstline and lastline select a range of lines:
\documentclass{article}
\usepackage{listings}
\begin{filecontents*}[overwrite]{fib.py}
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
print(fib(10))
\end{filecontents*}
\begin{document}
% the whole file
\lstinputlisting[language=Python, caption={fib.py}]{fib.py}
% only lines 1 to 5, numbered from 1
\lstinputlisting[language=Python, firstline=1, lastline=5,
numbers=left]{fib.py}
\end{document}The filecontents* block only creates fib.py so the example is self-contained; in your project the file already exists. Paths are relative to the main .tex file, e.g. \lstinputlisting{code/fib.py}.
Styling Code with \lstset
\lstset in the preamble sets options for every listing. For several looks in one document, name each with \lstdefinestyle and pick one per listing with style=. A complete, readable style:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\definecolor{codebg}{rgb}{0.96,0.96,0.96}
\definecolor{codegreen}{rgb}{0.15,0.5,0.15}
\definecolor{codepurple}{rgb}{0.55,0.1,0.55}
\lstdefinestyle{mystyle}{
backgroundcolor=\color{codebg},
basicstyle=\ttfamily\footnotesize,
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{codegreen}\itshape,
stringstyle=\color{codepurple},
numbers=left,
numberstyle=\tiny\color{gray},
numbersep=8pt,
frame=single,
rulecolor=\color{gray!50},
breaklines=true,
showstringspaces=false,
tabsize=4,
captionpos=b
}
\lstset{style=mystyle}
\begin{document}
\begin{lstlisting}[language=Python, caption={Counting words}]
from collections import Counter
def top_words(text, n=3):
# split on whitespace and count each word
counts = Counter(text.lower().split())
return counts.most_common(n)
print(top_words("the cat and the hat and the bat"))
\end{lstlisting}
\end{document}| Option | What it does |
|---|---|
basicstyle | Font of all code, e.g. \ttfamily\small |
keywordstyle, commentstyle, stringstyle | Look of keywords, comments and strings |
numbers=left | Line numbers (numberstyle sets their font) |
firstnumber=10 | Start numbering at 10 |
frame=single | Box around the code; lines, tb, leftline are lighter |
breaklines=true | Wrap long lines instead of running into the margin |
showstringspaces=false | Hide the ␣ marks inside strings |
tabsize=4 | Width of a tab character |
escapeinside={(*}{*)} | Run LaTeX inside (* ... *) in the code, e.g. math |
morekeywords={self} | Highlight extra words as keywords |
For a framed, colored box with a title bar around the code, the tcolorbox package has a listings library; see the tcolorbox guide. Colors are defined as in the colors guide.
Syntax Highlighting with minted
minted hands the code to Pygments, the highlighter many websites use, so it colors every token correctly and knows hundreds of languages. The price is an external program: Pygments must be installed (pip install Pygments), and LaTeX must be allowed to run it with the -shell-escape flag.
\documentclass{article}
\usepackage{minted}
\setminted{fontsize=\small, linenos, frame=lines, breaklines}
\begin{document}
\begin{minted}{python}
def greet(name: str) -> str:
return f"Hello, {name}!"
\end{minted}
Inline: \mintinline{python}|greet("Ada")|.
\end{document}Compile it with shell escape enabled:
pdflatex -shell-escape main.tex
latexmk -pdf -shell-escape main.texOther useful options are style=friendly (any Pygments color scheme), bgcolor and \inputminted{python}{file.py} for files. Captions work by wrapping the code in \begin{listing} with \caption and \label. Recent minted versions (3.x) use a helper program that up-to-date TeX distributions can allow under restricted shell escape; with older setups the full -shell-escape flag is required. Shell escape lets a document run programs, so only enable it for documents you trust.
verbatim and Inline Code with \verb
The verbatim environment needs no package: it prints its contents in a monospaced font with every character as typed. \verb does the same inline; the character right after \verb is the delimiter, so pick one that does not appear in the code. With listings loaded, \lstinline works the same way but applies the current language style.
\documentclass{article}
\usepackage{listings}
\lstset{basicstyle=\ttfamily, language=Python}
\begin{document}
\begin{verbatim}
$ python3 script.py --input data.csv
100% done, {42} rows, total = $1,024
\end{verbatim}
Run \verb|pip install numpy| first, or \verb+x|y+ when the code has a bar.
The call \lstinline|len(items)| is highlighted as Python.
Plain monospace without verbatim: \texttt{x\_max = 10\%}.
\end{document}verbatim does not wrap long lines; the fancyvrb package adds frames, line numbers and font sizes to it with the Verbatim environment. Neither \verb nor any verbatim environment can go inside the argument of another command; see the errors below.
Common Errors and Fixes
| Message or symptom | Cause | Fix |
|---|---|---|
| Package minted Error: You must invoke LaTeX with the -shell-escape flag | minted cannot run Pygments without shell escape | Compile with -shell-escape (or turn it on in the editor); otherwise switch to listings |
| Package minted Error: You must have ‘pygmentize’ installed | Pygments is missing or not on the PATH LaTeX sees | pip install Pygments, then restart the editor |
| Package Listings Error: Couldn't load requested language | The language is not built in (e.g. JavaScript, Rust, Go) or is misspelled, or a dialect is missing | Check the name, add the dialect ({[Sharp]C}), or define it with \lstdefinelanguage |
| Accented letters jump to the start of a word, vanish, or give Invalid UTF-8 byte sequence | listings reads one byte at a time under pdfLaTeX and cannot handle multi-byte UTF-8 | Add extendedchars=true plus a literate mapping (below), or compile with XeLaTeX/LuaLaTeX, or use minted |
| LaTeX Error: \verb illegal in command argument, or Missing $ inserted from code in a footnote | \verb or a listing inside \section, \footnote, \caption or a macro argument | Use \texttt with escaped characters there, or \lstinline outside the argument |
| Code runs off the right margin | Long lines are not wrapped by default | breaklines=true in \lstset (or breaklines for minted) |
| Odd ␣ symbols in strings | listings marks spaces inside strings | showstringspaces=false |
| Indentation is wrong after a tab | Tabs are expanded to 8 columns | tabsize=4, or convert tabs to spaces |
For UTF-8 inside lstlisting with pdfLaTeX, map each character you use to a LaTeX command. The number after each replacement is its width in characters:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings}
\lstset{
extendedchars=true,
literate={á}{{\'a}}1 {é}{{\'e}}1 {ü}{{\"u}}1 {ö}{{\"o}}1 {ñ}{{\~n}}1 {ú}{{\'u}}1
}
\begin{document}
\begin{lstlisting}[language=Python]
nombre = "José Núñez" # señal, über, schön
\end{lstlisting}
\end{document}Only the characters listed are mapped, so add every one your code contains (an Ñ or ç here would still need its own entry under pdfLaTeX). With XeLaTeX or LuaLaTeX, or with minted, no mapping is needed.
Frequently Asked Questions
How do I put code in a LaTeX document?
Load the listings package with \usepackage{listings} and wrap the code in \begin{lstlisting}[language=Python] … \end{lstlisting}. For a file on disk use \lstinputlisting[language=Python]{script.py}, and for code inside a sentence use \lstinline|x = 1| or \verb|x = 1|. The verbatim environment prints code with no highlighting and needs no package.
What is the difference between listings and minted?
listings is written in TeX, needs no external program and works on every compiler, but its highlighting only knows keywords, comments and strings. minted calls the Python program Pygments, so it highlights far more languages more accurately, but it needs Pygments installed and LaTeX run with -shell-escape. Use listings when you cannot control the compiler, minted when you can.
How do I add colors and line numbers to a listing?
Set them with \lstset in the preamble, after loading xcolor: basicstyle=\ttfamily\small for the font, keywordstyle=\color{blue}, commentstyle=\color{gray}, stringstyle=\color{red} for the colors, numbers=left with numberstyle=\tiny for line numbers, and frame=single for a box. \lstdefinestyle lets you name a style and apply it with style=name.
Why does minted say “You must invoke LaTeX with the -shell-escape flag”?
minted runs Pygments as an external program, which LaTeX blocks by default. Compile with pdflatex -shell-escape (or latexmk -shell-escape), enable shell escape in your editor settings, and make sure Pygments is installed (pip install Pygments). If you cannot enable shell escape, switch to the listings package, which needs no external program.
Which languages does the listings package support?
Around a hundred, including Python, Java, C, C++, Matlab, R, SQL, HTML, XML, bash, Fortran, Haskell and TeX. Language names are case-insensitive, and some take a dialect in brackets, such as [Sharp]C for C#. JavaScript, Rust, Go, Kotlin and Swift are not built in; define them with \lstdefinelanguage or use minted.
How do I write inline code in LaTeX?
Use \verb|code| for plain monospaced text; the delimiter can be any character that does not appear in the code. With the listings package, \lstinline|code| also applies the current language highlighting, and minted offers \mintinline{python}|code|. \verb cannot be used inside the argument of another command such as \section or \footnote; use \texttt with escaped special characters there.
Next Steps
- Code Listings in LaTeX (blog) – More examples of displaying programs in documents
- Algorithms in LaTeX – Pseudocode with algorithm2e and algpseudocode
- Colors in LaTeX – Defining the colors used in a code style
- Special Characters – Escaping %, $, _ and & outside code
- Boxes and Frames – Frames around text and code
- Learn LaTeX: Tutorial for Beginners – The basics, from the first document up
Free LaTeX Tools
- LaTeX Preview – Try listings styles with a live PDF preview
- AI LaTeX Generator – Generate LaTeX from text descriptions
- LaTeX Symbols Reference – Browse math operators and special characters
Related Articles
Compile LaTeX from Claude Code or Cursor with the Octree MCP Server
Fraction Symbols (½ ⅓ ¾): Every Unicode Fraction and How to Type Them
LaTeX Code Listings: Display Programming Code Beautifully
Pseudocode Generator: Write Algorithms in LaTeX
Format code listings faster with AI
Octree's AI editor sets up a listings style for your language, explains “Couldn't load requested language” and UTF-8 errors, and compiles your document in seconds.
Try Octree Free →