hilite
A Python syntax highlighting library powered by Oniguruma. Bring a TextMate grammar and a theme, and hilite turns your code into self-contained HTML.
Getting started
Use Python 3.14 or newer in a virtual environment:
python -m pip install hilite
Prebuilt wheels are available for CPython 3.14 on Linux x64, Windows x64, and macOS 11+ on Apple Silicon. Other configurations build from source and need Rust and a C compiler. On Windows, use Visual Studio Build Tools with the C++ tools.
Bring your own grammar and theme files. JSON and XML plist formats are supported; full language grammars and themes aren't bundled with the package.
from hilite import Theme, Highlighter, GrammarRegistry
registry = GrammarRegistry()
registry.register_file('grammars/python.tmLanguage.json', language='python', aliases=('py',))
theme = Theme.from_file('themes/dark-plus.json')
highlighter = Highlighter(registry)
html = highlighter.highlight(
'def greet(name):\n return f"Hello, {name}!"',
language='python',
theme=theme,
)
Reuse your Highlighter instance to keep parsed grammars and compiled patterns
cached. The native extension bundles Oniguruma. Prebuilt wheels install without
Rust or a C compiler.
You can also import grammars from an installed VS Code extension:
registry.import_extension(r'C:\Users\me\.vscode\extensions\publisher.language-version')
Pass the directory containing the extension's package.json. The importer reads
its grammar files without running extension code. Register any external grammars
it depends on, and keep the original licenses when copying grammar or theme files.
Highlighting doesn't download anything.
Make it your own
Add line numbers and emphasize a line:
from hilite import HtmlLayout, LineOptions, LineSelection
html = highlighter.highlight(
'def greet(name):\n return f"Hello, {name}!"',
language='python',
theme=theme,
layout=HtmlLayout(font_size='14px', padding='1.25rem'),
lines=LineOptions(numbers=True, emphasize=LineSelection(lines={2})),
)
Line selections start at 1. Use ranges=[(2, 5)] for an inclusive range or
number_start=100 to change the displayed numbering. The gutter stays separate
from the code, so copying code doesn't include line numbers.
Load a theme with Theme.from_file(), build one with Theme and ThemeRule, or
pass overrides to force a style over the theme:
from hilite import Style, ThemeRule
html = highlighter.highlight(
'# a comment',
language='python',
theme=theme,
overrides=(ThemeRule('comment', Style(foreground='#8a9199', italic=False)),),
)
If you want to render the same code with several themes, call
highlighter.tokenize(source, language='python') once and pass the result to
render_html(tokens, theme=theme). Tokens retain their scope stacks and Python
string offsets.
Try the examples
From a checkout, these commands create HTML pages you can open in a browser:
python -m examples.basic_snippets -o language-gallery.html
python -m examples.themes_and_overrides -o theme-gallery.html
python -m examples.lines_and_layout -o line-layout.html
The examples include small demo grammars for Python, JavaScript, HTML, JSON, and
shell, so they work without extra downloads. They cover the snippets shown, rather
than every feature of those languages. See
import_extension.py for highlighting a file with
an installed VS Code extension.
Native builds
Wheels include the native extension and Oniguruma 6.9.10. Source installs compile the extension automatically and require a successful native build. Cargo may download its locked dependencies during compilation.
CI builds and tests CPython 3.14 wheels on Linux x64, Windows x64, and macOS Apple Silicon. Linux wheels require glibc 2.28 or newer. Other Python versions and platforms aren't covered by CI.
Invalid patterns raise an error with the grammar and rule location. Call
highlighter.validate('python') to check a grammar before using it.
A few limits to know about
TextMate support includes multiline rules, nested repositories, capture
retokenization, external includes, and injections. Selectors can use grouped
alternatives and exclusions, such as (string | comment) - comment.block, plus
&, comma alternatives, direct-parent paths (source > string), and wildcard
scope segments (source.*). Injection selectors also support L: and R: priority.
Merge theme includes before loading a theme. Capture styling stays within the consuming match, and grammar cycles that make no progress raise an error.
ResourceLimits lets you cap input size, line length, nesting, token count, and
execution time. Oniguruma also limits backtracking and match-stack use, but a
running search can't be interrupted by a wall-clock deadline. Use a separate,
killable process if you need a hard deadline for untrusted input or grammars.
Code and HTML attributes are escaped. Output uses inline styles, which your page's
Content Security Policy or sanitizer may block. Only pass trusted values to
HtmlLayout.trusted_css. Line endings become LF in the rendered HTML; control
characters that can't round-trip through HTML are rejected.
Development
Create and activate a virtual environment, then install the development extras:
python -m pip install -e ".[dev,browser-test]"
python -m pytest
python -m ruff check .
python -m ruff format --check .
python -m mypy
python -m build
python -m twine check --strict dist/*
Editable installs build the native extension required by the test suite.
Browser tests need Chromium; set HILITE_BROWSER to its executable path to
enable them. The suite checks token scopes against pinned TextMate reference
fixtures without needing Node.
After changing native code, rebuild with python native/build.py --inplace
or rerun the editable install. python -m build creates a source archive and a
platform-specific native wheel. Check Rust changes with
cargo fmt --manifest-path native/Cargo.toml --check and
cargo clippy --manifest-path native/Cargo.toml --lib -- -D warnings.
bench_highlighter.py measures highlighting across
languages, input sizes, and layouts. Run it with --help for the available options.
The test workflow checks Python 3.14 on Linux, Windows, and macOS. It builds native wheels from the source archive, then tests the installed wheels with coverage and Chromium. Linux wheels use manylinux.
The release workflow runs those checks again when
a GitHub release is published. The tag, such as v0.1.0, must match the
version in pyproject.toml; prereleases and manual runs only validate. Publishing
uses the pypi environment and requires a PyPI trusted publisher configured for
release.yml. It uploads the distributions that passed CI.
Release files for hilite 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hilite-0.1.0.tar.gz | 471.0 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hilite-0.1.0-cp314-cp314-win_amd64.whl | CPython 3.14 | CPython 3.14 | Windows x86-64 | Details |
| hilite-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl | CPython 3.14 | CPython 3.14 | Linux glibc 2.28+ x86-64 | Details |
| hilite-0.1.0-cp314-cp314-macosx_11_0_arm64.whl | CPython 3.14 | CPython 3.14 | macOS 11.0+ ARM64 | Details |
Total release size: 1.8 MB
Release files / hilite-0.1.0.tar.gz
| Download URL | hilite-0.1.0.tar.gz |
|---|---|
| Size | 471.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
73bdf12774a07a9c56114ba1afc2783fb65beea6f0a9231dfd4c8522388fd65f
|
|
BLAKE2b-256 checksum How to use checksums |
bfa905052d7d8166d387c5d3cd440ecbd0fd8e25d80920f1ca83db7267f48b69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / hilite-0.1.0-cp314-cp314-win_amd64.whl
| Download URL | hilite-0.1.0-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 374.0 kB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
ea4db83f2dceac66ce793381858fa3bb4b45ff1dae38ec8ecd4b0f6da55198a8
|
|
BLAKE2b-256 checksum How to use checksums |
33d1b5ab3f61e4082d5a266c29ae5cf21d80aec97edede27c82f1c20e5981235
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / hilite-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl
| Download URL | hilite-0.1.0-cp314-cp314-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 515.9 kB |
| Tags | CPython 3.14 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
ac924c924c5e5ee77aa5cbce6072d678eecc930b46993513432e9c14246c930e
|
|
BLAKE2b-256 checksum How to use checksums |
5f66bcca11a1cd76bdb427d8393aa37064356bac520167c86022fa79cb15a728
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / hilite-0.1.0-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | hilite-0.1.0-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 461.4 kB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
fbf4e8966de76196128821b731cf0575211e3460e4c1aead3e26cc5d4f9c5fc2
|
|
BLAKE2b-256 checksum How to use checksums |
c4a6bffe48528d82732520eccd43ac874fea1c08cc46b329572bb56324c7ca50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log