QuickJax
Zero-dependency MathJax v4 SVG renderer for Python, powered by QuickJS.
QuickJax lets you convert LaTeX math expressions to self-contained SVG strings entirely within your Python process — no Node.js, no subprocess calls, no network requests.
Features
- Pure in-process rendering — MathJax v4 runs inside an embedded QuickJS engine via the
quickjsPython library. - Self-contained SVG output — Every rendered SVG carries its own font glyphs (
fontCache: "local"); no external CSS or fonts required. - 23 TeX extensions included out of the box: AMS, physics, mhchem, mathtools, braket, cancel, color, and more.
- Display & inline modes supported.
- Python 3.8+ compatible.
Installation
pip install quickjax
The only runtime dependency is the
quickjspackage (a C extension embedding the QuickJS engine, about 2 MB in size). No Node.js installation is needed.
Quick Start
from quickjax import render
# Display mode (default)
svg = render(r"E = mc^2")
# Inline mode
svg = render(r"\alpha + \beta", display=False)
# Write to file
with open("equation.svg", "w") as f:
f.write(svg)
Using the Renderer Class
For batch rendering, instantiate MathJaxRenderer once to amortize the JS context creation (~0.3 s):
from quickjax import MathJaxRenderer
renderer = MathJaxRenderer()
expressions = [
r"\int_0^\infty e^{-x}\,dx = 1",
r"\nabla \times \mathbf{E} = -\frac{\partial \mathbf{B}}{\partial t}",
r"\mathbb{R}^n",
]
for i, expr in enumerate(expressions):
svg = renderer.render(expr)
with open(f"eq_{i}.svg", "w") as f:
f.write(svg)
API Reference
render(latex, *, display=True) -> str
Module-level convenience function. Creates a shared MathJaxRenderer lazily on first call.
| Parameter | Type | Default | Description |
|---|---|---|---|
latex |
str |
— | LaTeX expression (without $ delimiters) |
display |
bool |
True |
True for display mode, False for inline |
Returns: A self-contained <svg>…</svg> string.
Raises: MathJaxRenderError if the expression cannot be rendered.
class MathJaxRenderer
| Method | Description |
|---|---|
__init__() |
Load the MathJax JS bundle into a QuickJS context. |
render(latex, *, display=True) -> str |
Render LaTeX to SVG. Same parameters as the module-level function. |
Supports use as a context manager (with MathJaxRenderer() as r: …).
class MathJaxRenderError
Subclass of Exception. Raised when MathJax cannot parse or render the given LaTeX input.
Supported TeX Extensions
ams · newcommand · boldsymbol · braket · cancel · color · enclose · extpfeil · html · mhchem · noerrors · noundefined · physics · mathtools · amscd · action · bbox · unicode · verb · textmacros · textcomp · cases
Development
Prerequisites
- Python 3.8+
- Node.js (build-time only, for bundling MathJax)
esbuild(installed automatically via npm)
Building the JS Bundle
bash build_bundle.sh
This runs npm install in renderer_src/ and produces quickjax/js/mathjax_bundle.js (~4.1 MB minified).
Running Tests
pip install pytest
pytest tests/ -v
How It Works
- Build time —
esbuildbundles MathJax v4 (mathjax-full@4.0.0-beta.7) plus all 26 dynamic font files frommathjax-modern-fontinto a single IIFE JavaScript file. - Runtime —
MathJaxRenderer.__init__()creates a QuickJS context (4 MB stack / 128 MB heap) and evaluates the bundle once. - Render — Each
render()call invokesglobalThis.render(latex)inside that context. MathJax'sliteAdaptorprovides a virtual DOM; the SVG output is extracted and returned as a pure<svg>string.
License
MIT
Metadata
Release files for quickjax 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 | Provenance | Actions |
|---|---|---|---|---|
| quickjax-0.1.0.tar.gz | 1.3 MB | Without provenance | Details for quickjax-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| quickjax-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for quickjax-0.1.0-py3-none-any.whl |
Total release size: 2.6 MB
Release files / quickjax-0.1.0.tar.gz
| Download URL | quickjax-0.1.0.tar.gz |
|---|---|
| Size | 1.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ffc2065ab357f34091c743c659501184c0bce17d4827b26e3b193fe3ceb8be76
|
|
BLAKE2b-256 checksum How to use checksums |
d4c8845d366f401d50ac57d378de9892e033efa1a396a9d5db04268ac3d69085
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / quickjax-0.1.0-py3-none-any.whl
| Download URL | quickjax-0.1.0-py3-none-any.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cdcde6770598e8dda805cffd033328ec0610c250fc9515b1451a53a9f641cca1
|
|
BLAKE2b-256 checksum How to use checksums |
c2bb37927ee314fd7f6d2cc05d0f029fb28e411b6b9ee569474ed9a15f5175d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Security for quickjax 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.