mrkeyoor.com_
Wed 05 Aug 19:52 UTC
PyPIUtilsupdated 05 Aug 2026

pygments

Pygments is the standard Python syntax highlighter. You hand it source code as a string, pick a lexer for the language and a formatter for the output, and it returns highlighted text as HTML, LaTeX, RTF, ANSI terminal escapes, or even images. It ships lexers for over 500 languages and text formats plus dozens of color styles, and it powers the code blocks in Sphinx, MkDocs, Jupyter, and the rich terminal library. There is also a pygmentize command line tool for one-off highlighting. Everything is pure Python and regex-based, which is why coverage is so broad and also why it has known performance limits on hostile input.

Verdict

The default and mostly unquestioned choice for syntax highlighting anywhere in Python, with language coverage nothing else matches. Just do not point it at untrusted input without a timeout, and do not use it as a reason to route browser highlighting through a Python backend.

API stability5/5The highlight/lexer/formatter API has been recognizably the same since the 2.x line began; new releases add lexers and styles far more often than they change interfaces.
Docs4/5pygments.org covers the API, the CLI, and writing custom lexers and styles well, but discovering the right formatter options often means reading docstrings and source.
Maintenance4/5Volunteer-run but genuinely active: pushed July 2026 with steady minor releases, though the open issues and PRs count sits near 600 because lexer requests accumulate faster than maintainers can review them.
Ecosystem5/5Roughly 306M weekly downloads, and it is the highlighting engine inside Sphinx, MkDocs, Jupyter, and rich, so third-party styles and lexer plugins are plentiful.

Use it if

  • You render code blocks to HTML server-side in a blog engine, documentation generator, wiki, or code review tool and want one dependency that covers essentially every language
  • You need output targets beyond HTML: LaTeX for papers, RTF, SVG, or ANSI escapes for terminal display
  • You need lexers for niche or legacy languages (COBOL, VHDL, TOML dialects, config formats) that JavaScript highlighters never bothered with
  • You are already inside the Sphinx, MkDocs, or Jupyter ecosystem, where Pygments is the built-in highlighting engine and custom styles or lexers plug straight in
Skip it if

Setup reality

pip install Pygments is pure Python with zero dependencies, so installing is the easy part. The real setup work is the HTML/CSS contract: HtmlFormatter emits span classes by default, so you must generate a stylesheet with get_style_defs() and ship it, or switch to noclasses=True inline styles and accept the bloat. Lexer selection is on you; guess_lexer() is genuinely unreliable, so pass a filename or explicit language whenever possible. If input is untrusted, you need a process-level timeout, which the library will not do for you.

Patterns

Highlight a code string to HTMLhighlight-to-html

from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter

code = 'print("hello")'
html = highlight(code, PythonLexer(), HtmlFormatter())

The output is a <div class="highlight"> full of span classes. It is unstyled until you also ship the CSS from get_style_defs().

Generate the stylesheet for a color stylegenerate-css

from pygments.formatters import HtmlFormatter

formatter = HtmlFormatter(style="monokai")
css = formatter.get_style_defs(".highlight")
with open("pygments.css", "w") as f:
    f.write(css)

Regenerate the CSS whenever you change style=, since class-to-color mappings differ per style. The selector argument scopes the rules.

Pick a lexer from a filenamelexer-by-filename

from pygments.lexers import get_lexer_for_filename
from pygments.util import ClassNotFound

try:
    lexer = get_lexer_for_filename("app.tsx")
except ClassNotFound:
    from pygments.lexers import TextLexer
    lexer = TextLexer()

Prefer the filename or get_lexer_by_name over guess_lexer(code), which misidentifies short snippets constantly. Falling back to TextLexer beats crashing.

Highlight for the terminal with ANSI colorsterminal-output

from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import Terminal256Formatter

print(highlight('{"ok": true}', JsonLexer(), Terminal256Formatter(style="monokai")))

Terminal256Formatter covers most modern terminals; TerminalTrueColorFormatter exists for 24-bit color. Neither checks whether stdout is a TTY, that is your job.

Add line numbers to HTML outputline-numbers

from pygments.formatters import HtmlFormatter

formatter = HtmlFormatter(linenos="table", linenostart=10)

linenos="table" keeps numbers out of copy-paste selection by using a two-column table; linenos="inline" puts them in the text flow where users will copy them.

Emphasize specific lineshighlight-specific-lines

from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter

formatter = HtmlFormatter(hl_lines=[2, 3])
html = highlight(code, PythonLexer(), formatter)

Highlighted lines get a .hll class; the background color comes from the style's CSS, so it only shows once the stylesheet is loaded.

Inline styles for email or CSS-less contextsinline-styles

from pygments.formatters import HtmlFormatter

formatter = HtmlFormatter(noclasses=True, style="default")

noclasses=True writes style attributes on every span. Output size grows a lot, but it is the only reliable option for HTML email.

List styles and lexers programmaticallylist-available-styles

from pygments.styles import get_all_styles
from pygments.lexers import get_all_lexers

print(sorted(get_all_styles()))
for name, aliases, filenames, mimetypes in get_all_lexers():
    print(name, aliases)

Useful for building a theme or language picker. get_all_lexers() yields metadata tuples without importing every lexer module.

Highlight a file from the command linecli-pygmentize

pygmentize -f html -O full,style=monokai -o out.html script.py

# or straight to the terminal:
pygmentize script.py

-O full wraps output in a complete HTML document with embedded CSS, handy for one-offs. Without -f, the formatter is guessed from the output filename.

Highlight untrusted input with a hard timeoutguard-untrusted-input

import multiprocessing as mp
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter

def work(code, lang, q):
    q.put(highlight(code, get_lexer_by_name(lang), HtmlFormatter()))

def safe_highlight(code, lang, timeout=5):
    q = mp.Queue()
    p = mp.Process(target=work, args=(code, lang, q))
    p.start()
    p.join(timeout)
    if p.is_alive():
        p.kill()
        return None
    return q.get()

The README itself says execution time is unbounded on hostile input. A thread cannot be killed mid-regex in Python, so a separate process is the only real guard.

Alternatives

PackageRegistryPick it when
richPyPIYou want highlighted output in the terminal from your own Python app; it uses Pygments internally with a nicer API.
shikinpmYou are in a JS/TS build pipeline and want VS Code-accurate highlighting via TextMate grammars.
highlight.jsnpmYou want quick client-side highlighting in the browser with automatic language detection.