KaTeX and MathJax are JavaScript libraries that render LaTeX math syntax in web browsers. They’re how most math ends up on the web today. This chapter explains how each works, when to choose one over the other, and how to set them up.
How They Work
Both libraries take the same input, LaTeX math syntax, and produce rendered output in the browser. But they do it differently.
KaTeX
KaTeX (created by Khan Academy) renders math by generating HTML with CSS classes that position elements precisely. No images, no MathML (by default), just spans and absolute positioning.
- Speed: Extremely fast. Renders synchronously. No layout reflow.
- Output: HTML + CSS. Lightweight.
- Limitations: Supports a subset of LaTeX math commands. Some obscure symbols or environments are missing.
- Size: ~100 KB (minified + gzipped).
MathJax
MathJax (now at version 3) is more comprehensive. It parses LaTeX or MathML input and can output HTML, SVG, or MathML.
- Speed: Slower than KaTeX but acceptable for most pages.
- Output: HTML-CSS, SVG, or MathML. Configurable.
- Coverage: Near-complete LaTeX math support. Handles edge cases that KaTeX skips.
- Size: ~200-300 KB depending on configuration.
- Accessibility: Built-in assistive technology support.
Performance Comparison
- Metric: First render (single equation) | KaTeX: 2-5 ms | MathJax 3: 20-50 ms | Winner: KaTeX
- Metric: 100 equations | KaTeX: 50-100 ms | MathJax 3: 200-500 ms | Winner: KaTeX
- Metric: Library load time | KaTeX: 30-60 ms | MathJax 3: 80-150 ms | Winner: KaTeX
- Metric: Bundle size (gzipped) | KaTeX: ~100 KB | MathJax 3: ~250 KB | Winner: KaTeX
- Metric: LaTeX command coverage | KaTeX: ~85% | MathJax 3: ~99% | Winner: MathJax
- Metric: Accessibility | KaTeX: Basic | MathJax 3: Excellent | Winner: MathJax
Important: Rule of thumb:
- Use KaTeX when performance matters (many equations, mobile users, static sites) and your math uses common commands.
- Use MathJax when you need full LaTeX coverage, accessibility features, or when rendering math from user input (where you can’t control what commands are used).
Setting Up KaTeX
CDN (Quickest)
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16/
dist/katex.min.css">
<script defer
src="https://cdn.jsdelivr.net/npm/katex@0.16/
dist/katex.min.js"></script>
<script defer
src="https://cdn.jsdelivr.net/npm/katex@0.16/
dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body);">
</script>
This auto-renders all $...$ and <!--M5--> on the page.
Programmatic API
import katex from 'katex';
// Render to a DOM element
katex.render("E = mc^2", element, {
displayMode: true,
throwOnError: false
});
// Render to an HTML string
const html = katex.renderToString("\\frac{a}{b}", {
displayMode: false
});
Server-Side Rendering
KaTeX can render at build time (no JavaScript needed in the browser):
const katex = require('katex');
const html = katex.renderToString("\\int_0^1 f(x)\\,dx", {
displayMode: true
});
// Embed `html` in your page template
// Only the CSS file is needed in the browser
Tip: Server-side rendering with KaTeX is the fastest approach for the user. The math is pre-rendered at build time. The browser only loads the KaTeX CSS (no JS). This is what we use at https://gauravtiwari.org.
Setting Up MathJax
CDN
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\<!--M2-->']],
displayMath: [['<!--M0-->'], ['\<!--M6-->']]
},
svg: { fontCache: 'global' }
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/
es5/tex-svg.js">
</script>
Output Formats
MathJax 3 offers three output modes:
- Output:
tex-chtml| Characteristics: HTML output. Fast, scalable, good for most uses. - Output:
tex-svg| Characteristics: SVG output. Highest quality, no font loading needed. Slightly larger. - Output:
tex-mml-chtml| Characteristics: Accepts both LaTeX and MathML input.Node.js Server-Side
require('mathjax').init({
loader: { load: ['input/tex', 'output/svg'] }
}).then((MathJax) => {
const svg = MathJax.tex2svg('\\frac{a}{b}', {
display: true
});
const html = MathJax.startup.adaptor
.outerHTML(svg);
});
Syntax Differences
Both accept standard LaTeX math. The differences are in edge cases:
- Feature: Basic math (
\frac,\sqrt, etc.) | KaTeX: Yes | MathJax: Yes - Feature:
\textand\textbf| KaTeX: Yes | MathJax: Yes - Feature:
align,gather,cases| KaTeX: Yes | MathJax: Yes - Feature:
\newcommand| KaTeX: Limited | MathJax: Full - Feature:
\DeclareMathOperator| KaTeX: No | MathJax: Yes - Feature:
\require(load extensions) | KaTeX: No | MathJax: Yes - Feature:
physicspackage commands | KaTeX: No | MathJax: With extension - Feature:
mhchem(chemistry) | KaTeX: Yes (built-in) | MathJax: Yes (extension) - Feature: Color (
\color,\colorbox) | KaTeX: Yes | MathJax: Yes - Feature:
\canceland\bcancel| KaTeX: Yes | MathJax: With extensionThe Rendering Pipeline
- Author writes LaTeX math syntax in their content source (Markdown, HTML, CMS).
- Build step (optional): KaTeX or MathJax renders math to HTML/SVG at build time.
- Browser receives the page. If pre-rendered, math displays immediately. If not, the JS library loads and processes the page.
- Output: Styled HTML spans (KaTeX), SVG paths (MathJax SVG mode), or HTML with font metrics (MathJax CHTML mode).
Configuring Delimiters
Both libraries need to know what delimiters mark math in your content:
renderMathInElement(document.body, {
delimiters: [
{ left: "<!--M1-->", display: true },
{ left: "\<!--M7-->", display: true },
{ left: "$", right: "$", display: false },
{ left: "\<!--M3-->", display: false }
],
throwOnError: false
});
Warning: Using single
$delimiters on pages with currency amounts causes conflicts. Consider using only<!--M4-->and<!--M8-->delimiters.
2. A build-time plugin processes the content, calling KaTeX to render each expression to HTML.
3. The rendered HTML is cached and served to visitors.
4. Only the KaTeX CSS file (no JavaScript) is loaded in the browser.
5. Fallback: if the server-side render fails, KaTeX JS loads and renders client-side.
This approach gives us the fastest possible page load while maintaining full math support.
Exercises
- Create an HTML page with KaTeX (CDN) that renders five different equations. Include both inline and display math.
- Repeat the exercise with MathJax and compare the output quality and load time.
- Set up server-side KaTeX rendering in a Node.js script. Render 10 equations and save the output as a static HTML file.
- Find three LaTeX commands that work in MathJax but not in KaTeX. Verify by testing in both.