// 2013 — 2026 · Khan Academy · Emily Eisenberg + Sophie Alpert · MIT · math in the browser at 100× MathJax speed

KaTeX:<math/>

KaTeX is a LaTeX math renderer for the browser at 100× MathJax speed. Started inside Khan Academy in 2013, open-sourced in 2014. Returns an HTML string synchronously, renders an equation in ~1ms, caches a 250KB bundle once. Every equation on this page (the one below included) is live KaTeX — see /code/language/latex for the LaTeX it implements a subset of.

2013Born inside Khan Academy
Emily Eisenberg + Sophie Alpert
~1msper equation render
synchronous, no layout shift
90%+LaTeX math coverage
"equations you see in papers"
~250KBgzipped total
vs MathJax ~1.6MB
KaTeX\sum \int \frac
\frac{a}{b}\sum_{i=1}^nrenderToStringdisplayModeauto-render\mathbb{R}Khan AcademyEmily EisenbergPre-Stashno MathML deps\int_0^1\ce{H2O}
scroll
01

What is KaTeX

KaTeX = a browser-side LaTeX math renderer from Khan Academy, MIT-licensed, written in TypeScript. Not a full LaTeX engine — math mode only: no \documentclass, no TikZ, no page layout. But it covers 90%+ of the math that shows up in real papers, and returns HTML synchronously — no FOUC, no layout shift.

Not a full LaTeX engine math-only

Math mode only. No \documentclass, TikZ, BibTeX, or page layout. A design choice, not a defect — tight scope is the only way you get 250KB in the browser. For the full LaTeX story see /code/language/latex.

Sync, one-shot, returns a string sync

renderToString(src) returns an HTML string immediately. No async, no promise, no font-load callback. First-class SSG / SSR citizen; no client-side flash. A different world from MathJax's async-everything model.

Outputs HTML+CSS, not MathML / SVG output

Default path is HTML elements + CSS positioning; the browser reuses its text rendering pipeline. Optional MathML overlay (output: 'htmlAndMathml') for a11y. Different from MathJax's default SVG path — one of the reasons it's fast.

No MathML dependency render

Doesn't require native MathML support — so Chrome / Safari / Firefox render pixel-identically. MathML Core only stabilised in 2023 and cross-engine differences remain large; KaTeX owns its rendering = looks the same everywhere.

mathjax.htmlasync
<script src="mathjax.js"></script>
<p>$\sum_{i=1}^n i$</p>

// load: 1.6MB
// parse + render: async
// font measurement: async
// result: equation arrives late, page jumps

// ~30ms / equation (v2)
// ~7–15ms / equation (v3)
katex.htmlsync
<link rel="stylesheet" href="katex.min.css">
<script>
  const html = katex.renderToString(
    '\\sum_{i=1}^n i'
  );  // returns string instantly
</script>

// load: 250KB (cached once)
// render: ~1ms, sync
// result: equation lands with HTML, zero jump
02

History : 1977 → 2026

KaTeX's arc breaks into four phases: the TeX/LaTeX ancestors (1977–2003) → the jsMath / MathJax era (2003–2013) → Khan Academy starts it + open-sources it (2013–2018) → mainstream adoption + the AI era (2019–2026). The full upstream LaTeX story is at /code/language/latex.

  1. 1977~1985

    TeX → LaTeX — KaTeX's ancestors

    Donald Knuth wrote TeX in 1977; Leslie Lamport built LaTeX as macros on top in 1985. KaTeX implements exactly the LaTeX math subset. The full story lives at /code/language/latex.

  2. 2003

    jsMath — the first browser TeX

    Davide Cervone (Union College) writes jsMath — the first serious attempt to put LaTeX math in the browser. GIF fallbacks, Adobe AFM fonts converted to TrueType — slow and ugly, but it opens the road for "math in the browser".

  3. 2009·08

    MathJax 1.0 — the gold standard

    Davide Cervone teams up with AMS / Design Science / SIAM and ships MathJax. Pure-JS, cross-browser, HTML+CSS / SVG / MathML output, auto font loading. For seven years almost every equation on the academic web is MathJax. But heavy: ~1.6MB default bundle, async parse + render, layout shift on long pages.

  4. 2010

    Khan Academy takes off — math video on the web

    Sal Khan's thousands of math problems from YouTube migrate into a web app. Early KA renders math via pre-rendered images or MathJax — a single practice page can carry hundreds of equations, and MathJax render time becomes student wait time. The pain that begets KaTeX gets buried here.

  5. 2013·09

    KaTeX is born inside Khan Academy

    Emily Eisenberg + Sophie Alpert (Sophie later joined Facebook's React core team) start it inside KA. The stated goal is blunt: "render math 100× faster than MathJax". The key insight: precompute font metrics at build time, never measure at runtime.

  6. 2014·09

    Open-sourced + the Pre-Stash technique

    KaTeX hits GitHub under MIT. "Pre-Stash" becomes the project's engineering shorthand — a ~30KB font-metric JSON ships inside the bundle so rendering is synchronous, ~1ms per equation, no FOUC, no layout shift. The first math renderer fast enough to be enjoyable on a long page.

  7. 2014

    Stack Exchange Math evaluates it

    The Mathematics Stack Exchange starts looking at KaTeX as a MathJax replacement. The eventual answer is both: KaTeX for simple expressions, MathJax fallback when KaTeX can't parse it. A hybrid pattern that several academic sites copy through 2014–2018.

  8. 2015

    0.5 — matrices, aligned, colour

    KaTeX 0.5 lands \begin{aligned}, \begin{pmatrix}, \color. Real-world coverage of "equations you'd see in a paper" jumps from ~60% to ~80%; every release after that fills out more of the LaTeX math subset.

  9. 2016

    Discourse adopts KaTeX as default

    Jeff Atwood's Discourse (the modern forum platform) switches its default math renderer to KaTeX from MathJax. Discourse owns the forum / community niche; once it flips, every open-source knowledge base on Discourse inherits KaTeX's speed.

  10. 2017

    GitHub adds math → switches to KaTeX

    GitHub adds math rendering to issues / PRs / READMEs. The first cut uses MathJax; GitHub later switches to KaTeX for both perf and bundle. From that point developers writing READMEs can drop $\int$ and get a real equation — a doc-habit shift across thousands of repos.

  11. 2017

    0.9 — the auto-render extension

    Adds renderMathInElement(): scan DOM text nodes, find $...$, $$...$$, \(...\) delimiters and replace in place. "Add KaTeX to your existing markdown site in one line" starts here.

  12. 2018

    0.10 — mhchem / copy-tex / MathML

    Three big additions in one cut: mhchem (chemistry like \ce{H_2O}), copy-tex (right-click a rendered equation, copy back the LaTeX source), and a MathML output mode for screen readers and accessibility. From here KaTeX is "good enough" for almost any teaching / explainer use case.

  13. 2019

    0.11 — full Unicode math mode

    Direct parsing of Unicode math like α, , (no need to type \alpha first). Aligns KaTeX with consumer apps like Notion / Substack / Quora where users paste Unicode directly.

  14. 2020~22

    Notion / Substack / Quora all flip to KaTeX

    Three big consumer platforms move within months of each other. The consumer-side "browser math" war is over: speed-first picks KaTeX, accessibility-first sticks with MathJax. They stop competing and each owns its lane. Hashnode, Roam, Logseq follow in the same window.

  15. 2022

    GitHub-Flavored Markdown specs math

    GFM spells out $inline$ and $$display$$ as math syntax; the renderer is KaTeX. "Drop an equation into your README" shifts from convention to spec — reach: every open-source project on GitHub.

  16. 2023

    0.16 — ESM + perf refactor

    Codebase moves to TypeScript, switches to ESM modules, parser is rewritten, render goes another notch faster. "Already fast enough" projects still squeezing perf — a sign of maturity, not decline.

  17. 2024

    Obsidian / Logseq / every note app

    Note-taking apps fully embrace KaTeX: Obsidian, Logseq, Anytype, Tana, Reflect. The same equation travels from notebook to blog to GitHub README rendered by the same engineKaTeX is the browser-side lingua franca of LaTeX math.

  18. 2025

    Maintenance mode + usage explosion

    KaTeX 0.16.x is in steady maintenance: occasional bug fixes, occasional edge LaTeX commands; no more big swings. Usage keeps climbing though — LLMs emit LaTeX, the browser renders it via KaTeX, AI chat UIs push KaTeX to all-time highs.

  19. 2026

    KaTeX in 2026 — the default browser math

    2026: KaTeX is the default browser math renderer. MathJax is alive but holds only the a11y / full-LaTeX market. This very page renders with it — see in the hero.

03

The Pre-Stash Technique : Why100x

KaTeX outruns MathJax by 10–100×, not from a clever algorithm, but from a single engineering call: precompute font metrics at build time, never measure them at runtime. The decision has a name: "Pre-Stash."

PRE-STASH

Why MathJax is slow font measurement = bottleneck

Rendering an equation requires knowing the width / height / side-bearings of every glyph — where to put the fraction bar, what to line super/subscripts against, how big to draw the root sign all depend on these numbers.

MathJax's approach: at runtime, drop the character into a hidden div and read getBoundingClientRect(). Every measurement triggers real layout, forcing reflow. A long equation does it hundreds of times, a page thousands — async, slow, jittery.

  • ~30ms per equation (v2) / ~7-15ms (v3)
  • Async: equations arrive late, page jumps
  • Shows $ raw $ until fonts arrive

KaTeX's answer precomputed JSON

At build time KaTeX extracts every glyph metric out of the TeX .tfm files, serialises it into fontMetricsData.js (~30KB) and bundles it directly.

At runtime KaTeX looks up the JSON, never the DOM. No reflow, no async font load, no getBoundingClientRect. Pure computation, output is an HTML string. 1ms per equation.

  • ~1ms per equation — 100× MathJax v2, 10× v3
  • Sync: equation lands with HTML, zero layout shift
  • Trade-off: locked to the bundled KaTeX fonts, no swap
// build-time (inside KaTeX source)
import { parseTfm } from './tfm-parser';
const metrics = {
  "Main-Regular": parseTfm('cmr10.tfm'),
  "Math-Italic": parseTfm('cmmi10.tfm'),
  // ... 16 KaTeX_* fonts, thousands of glyphs each
};
writeFileSync('fontMetricsData.js', `export default ${JSON.stringify(metrics)}`);

// runtime (in the browser)
import metrics from './fontMetricsData';  // instantly available
function getCharMetric(font, ch) {
  return metrics[font][ch.charCodeAt(0)];
}
// no DOM, no reflow, no font await

In one line: Pre-Stash is not algorithmic cleverness — it's moving the asynchrony into the build step. "Measure fonts in the user's browser" becomes "we already measured them before shipping". Same work, different point in time, and you go from 30ms async to 1ms sync. A textbook engineering trade-off.

04

Live Playground : KaTeXLive

Type LaTeX on the left and see live KaTeX rendering on the right (same engine as the rest of this page). What you type is what you render, synchronous, no await. Click a preset above for a classic.

LaTeX source → KaTeX renderlive sync
Tip: backslashes need doubling in a JS string; not here in the textarea
display mode (TeXBlock)
inline mode (TeX)
Sits inside a sentence like and flows with surrounding text.
05

LaTeX Coverage Matrix : Whatsupported

KaTeX implements 90%+ of LaTeX math mode. The left column is supported (with live rendered samples); the right is not supported (with the reason why). Every left-side sample is real live KaTeX.

Supported16
Fractions \frac
Sums \sum / integrals \int
Matrices pmatrix / bmatrix
Alignment aligned / cases
All Greek letters
Blackboard bold \mathbb
Cal / fraktur \mathcal \mathfrak
Binom \binom / root \sqrt
Braces / decorations \overbrace
Labelled arrows \xrightarrow
Colour / size
Generic \begin{array}
Full AMS symbols
Chemistry mhchem \ce
Custom macros option
Unicode math input
Not supported10
TikZ / PGF diagramsNeeds a full Lua / TeX engine
Asymptote graphicsSeparate C++ toolchain — won't fit in 250KB
\documentclass / page setupKaTeX renders math, not documents
\section / \chapterUse HTML <h1><h6>
BibTeX citations / bibliographyOutside math scope
Page layout / floatsThat's CSS's job, not KaTeX's
preamble \newcommand auto-loadmacros exist, but must be passed explicitly
eqnarrayLong deprecated anyway, use aligned
Arbitrary font substitutionLocked to the bundled KaTeX_* fonts
Live LaTeX compile errorsthrowOnError exists but isn't a full LaTeX error model
06

Performance vs MathJax : Numbers

Two axes: per-equation render time and bundle size. Numbers composite KaTeX's own benchmark, MathJax's official benchmark, and multiple 2024–25 blog measurements; device = mid-range laptop Chrome main thread. The gap is orders of magnitude, not factors.

Per-equation render time (lower is better)

x-axis normalised against ~50ms max · sourced from public benchmarks

KaTeX 0.16
~1ms
~1ms
MathJax v3 (HTML)
~7ms
~7ms
MathJax v3 (SVG)
~11ms
~11ms
MathJax v2 (legacy)
~30ms
~30ms
jsMath (2003)
~45ms
~45ms
KaTeX MathJax v3 MathJax v2 (legacy) jsMath (historical)

Bundle size (lower is better)

gzipped total · x-axis 100% = ~1.6MB MathJax default bundle

KaTeX (CSS + fonts)
~250KB
~250KB
KaTeX (JS only)
~75KB
~75KB
MathJax v3 (full)
~1.6MB
~1.6MB
MathJax v3 (lazy / core)
~560KB
~560KB
MathJax v2 (full)
~2.1MB
~2.1MB
KaTeX MathJax v3 MathJax v2
"

KaTeX's goal is fast. Every design decision is bent toward "the user sees every equation on a long page instantly": synchronous, no font loading, no reflow. Fast math, not all math.

— Emily Eisenberg (KaTeX co-author, Khan Academy)composite from the 2014 launch blog + GitHub README · paraphrased

In one line: KaTeX isn't algorithmically faster than MathJax — it chose not to do certain things (don't measure fonts, don't go async, don't render non-math). The speed comes from doing less, not from a trick. 10× isn't magic — it's determined by scope.

07

API Surface : TheCallSites

KaTeX's API is small enough to read in one glance: two main entries (renderToString / render), plus four contrib extensions (auto-render / mhchem / copy-tex / etc.) and a few wrapper libraries. The eight cards below cover 95% of real usage.

A

katex.renderToString()

Synchronous, returns an HTML string. Top pick for SSR / static generation — bake the output into HTML, ship zero JS to the client.

import katex from 'katex';

const html = katex.renderToString(
  '\\sum_{i=1}^n i^2',
  { displayMode: true }
);
// → <span class="katex-display">...</span>
B

katex.render()

Client-side: mutates a DOM node in place. No return value, side-effect rendering. Pairs with React effects / framework directives.

const el = document.getElementById('eq');
katex.render('E = mc^2', el, {
  throwOnError: false,
  errorColor: '#FF8E72'
});
C

The auto-render extension

One-line integration for legacy markdown / blog sites. Scans the DOM for $...$, $$...$$ and replaces in place.

import renderMathInElement from
  'katex/contrib/auto-render';

renderMathInElement(document.body, {
  delimiters: [
    { left: '$$', right: '$$', display: true },
    { left: '$',  right: '$',  display: false }
  ]
});
D

React wrapper

react-katex: <BlockMath> / <InlineMath>. This page uses useMemo + dangerouslySetInnerHTML directly — no extra dependency.

import { BlockMath } from 'react-katex';

<BlockMath
  math={'\\int_0^1 x^2\\,dx'}
/>
E

mhchem chemistry

Speaks the \ce{...} syntax. Required for teaching / chemistry sites.

import 'katex/contrib/mhchem';

katex.renderToString(
  '\\ce{2H2 + O2 -> 2H2O}'
);
F

copy-tex

Right-click and copy a rendered equation and your clipboard holds the LaTeX source, not the rendered HTML. Essential for academic / note workflows.

import 'katex/contrib/copy-tex';
// ↑ that's it. side-effect import.
G

SSR pipeline

SSG / SSR: call renderToString at build time → bake the HTML + katex.min.css into the page → client never loads KaTeX JS. This site's prediction long-form pages run exactly this way.

// build.ts
const body = mdAst.walk((eq) =>
  katex.renderToString(eq.src)
);
writeFile('out.html', body);
H

Error handling

throwOnError: false + errorColor = broken equations turn into red fallback text instead of crashing the page. Rule one for production.

katex.renderToString(input, {
  throwOnError: false,
  errorColor: '#FF8E72',
  strict: 'ignore'
});

SSR best practice

At build time render all equations and bake them into the HTML; the client only needs to link katex.min.css (~23KB). The KaTeX JS never has to ship to the client — that's exactly how the prediction long-form pages on this site work, and LCP benefits directly.

"The best client-side JS is JS you never ship. — Alex Russell (frequently quoted)"

08

KatexOptions Cookbook : Recipes

Every render / renderToString call takes a KatexOptions object. The 12 below are the ones real projects actually tweak, grouped by purpose.

core
option
displayMode: true

Display mode (centred, large) vs inline. The single boolean you tweak most often.

core
option
throwOnError: false

Parse errors don't throw, render as red fallback text. Always on in production.

core
option
errorColor: "#cc0000"

Fallback text colour. Pick something like #FF8E72 for dark themes.

macros
option
macros: { "\RR": "\mathbb{R}" }

Custom macros. Equivalent to \newcommand in LaTeX, but it doesn't auto-load from .tex files — pass them explicitly.

strict
option
strict: 'ignore'

How to treat non-standard LaTeX: 'error' / 'warn' / 'ignore'. ignore maximises consumer-input compatibility.

security
option
trust: true

Allows \href, \includegraphics. Never enable on user input — XSS surface.

output
option
output: 'htmlAndMathml'

Visuals via HTML+CSS, plus embedded MathML for screen readers. The a11y-friendly default.

output
option
fleqn: true

Display equations flush-left instead of centred. Mirrors certain journal styles.

i18n
option
minRuleThickness: 0.05

Minimum fraction-bar thickness (em). Stops hairlines on Retina screens.

i18n
option
maxSize: Infinity

Cap on \rule / \hspace sizes. Guards against malicious input blowing up the layout.

macros
option
maxExpand: 1000

Macro expansion limit. Stops bombs like \def\x{\x\x} from blowing up your server.

core
option
globalGroup: true

Across multiple katex.renderToString calls, macro definitions persist. Common in SSR batch rendering.

09

Ecosystem / Users / Tools : Ecosystem

2026 KaTeX users in production: GitHub, Notion, Discourse, Stack Exchange, Obsidian, Substack, Khan Academy, Quora, Logseq, Hashnode, Roam Research, every modern static-site generator (Hugo / Astro / Eleventy / Docusaurus / VitePress). The 12 cards below cover tools, wrappers and upstream / downstream anchors. Upstream LaTeX at /code/language/latex.

10

vs MathJax : TheRivalry

KaTeX and MathJax aren't the same product: one chases speed, the other chases full LaTeX + accessibility. Since 2020 they each own a lane and stopped competing head-on. The table below is honest, not a KaTeX victory lap.

KaTeXMathJax v3Note
Speed (per eq)~1ms sync~7-15ms async, sync optionalKaTeX 10×
Bundle size~250KB gzipped~1.6MB / ~560KB lazyKaTeX 6×
LaTeX coverage~90% of the math subsetNear-complete LaTeX math + packagesMathJax wins
AccessibilityHTML+CSS / optional MathMLNative MathML, perfect SR supportMathJax wins
Output formatHTML+CSS (default)SVG / MathML / HTML+CSSMathJax: more outputs
SSRSync from day oneOnly v3 added sync APIKaTeX wins
FontsLocked to KaTeX_* (Pre-Stash)Any font, swappableMathJax: flexible
Cross-browser identicalPixel-identicalDiffers in native MathML modeKaTeX wins
LicenseMITApache 2.0Both commercial-friendly
Release cadenceMaintenance (yearly)Active (quarterly)MathJax: bigger team
Primary usersConsumer: GitHub / Notion / Substack / note apps / AI chatAcademic: arXiv / publishers / journals / a11y-firstDifferent niches
2026 directionAI chat UI default · steadyHolding academia / a11yNo longer competing
11

Why KaTeX in 2026 : PickKaTeX

"Legacy tech" is the standard KaTeX misconception — 2024–2026 it had a usage explosion driven by AI chat UIs. Six cards on why it's still the right pick in 2026.

Synchronous render = zero layout shift

renderToString returns finished HTML. Unlike MathJax's async font measurement, long math-heavy pages don't jump around. CLS score goes straight to perfect.

katex.renderToString(src) // → instant string
// MathJax v2 was async, layout shifts when fonts arrive

~250KB, cached once

JS + CSS + KaTeX_* fonts together come to ~250KB gzipped, cached across pages. MathJax v3's full bundle is ~1.6MB — over 6× larger. An entire LCP tier on mobile.

// katex.min.css ≈ 23KB gzip
// katex.min.js  ≈ 72KB gzip
// fonts/*       ≈ 150KB gzip (woff2)

TypeScript + ESM + MIT

Post-0.16 the whole codebase is TS, with types shipped, ESM modules. License is MIT — commercial, teaching, closed-source: zero friction. Hits every 2026 "modern engineering" checkbox.

import katex, { KatexOptions } from 'katex';
// types ship with the package, no @types/* needed for opts
π

The "just enough" 90%

No TikZ, no BibTeX, no page layout — focus on LaTeX math, full stop. The result: 90%+ of real-world equations parse out of the box, the remaining 10% mostly covered by mhchem / macros. Tight scope, easier engineering.

// scope = math mode + AMS + a few envs
// not   = a whole TeX engine in JS
⟨⟩

SSR as a first-class citizen

renderToString was synchronous from day one — meaning SSG / SSR work without contortions: bake HTML at build, ship zero KaTeX JS to the client, only ~23KB of CSS.

// build step:
html.replace(MATH_RE, (s) =>
  katex.renderToString(s)
);

This page itself is proof

Every equation on the page you are reading is rendered by KaTeX live. No screenshots, no SVG, no MathJax. This right here. That is how light and natural it feels.

<TeX src={'\\Vert v \\Vert = ...'} />
// 5 lines, no library, just useMemo + dangerouslySetInnerHTML
12

Footguns : Pitfalls

KaTeX is simpler than MathJax, but four pitfalls show up over and over in issues / Stack Overflow. Know them once, save yourself the repeat.

PITFALL · 01

Backslash escaping in JS strings

LaTeX's \frac must be written '\\frac' in a JS string (double backslash to produce one). This is the #1 KaTeX bug: users paste a LaTeX source into JS, the equation doesn't render, and the backslash got eaten.

Fix: template literals + backticks don't help (backslash still needs escaping). For real relief, keep LaTeX strings in external .tex / .md files and read them in.

PITFALL · 02

\newcommand doesn't auto-load

The \newcommand{\RR}{\mathbb{R}} in your .tex preamble means nothing to KaTeX — there's no preamble concept. You must pass them via the macros option.

Fix: keep a project-level macros object, spread it into every render call, or wrap with a renderWithMacros(src) helper.

PITFALL · 03

auto-render delimiter collisions

auto-render defaults to $...$ for inline math. But "$100, $200" in a price list parses as $1$00, $2$00.

Fix: disable the single $ delimiter, keep only $$...$$ and \(...\); or escape prices as \$100.

PITFALL · 04

Import katex.min.css exactly once

import 'katex/dist/katex.min.css' belongs in your top-level entry. Importing it per component duplicates it in the bundle and flashes styles in dev.

For SSR / static generation: link katex.min.css straight from the HTML head; the client can skip the import entirely. The prediction pages on this site work that way.

13

Outlook : TheNext5Years

KaTeX in 2026 has entered "stable success" — feature work has slowed, but usage quietly climbs on the wave of LLMs emitting LaTeX. Four cards on what to expect over the next 3–5 years.

HOT · 2024+

LLM outputs LaTeX → KaTeX renders — the quiet KaTeX renaissance

KaTeX's biggest 2026 customer is every AI chat UI: ChatGPT, Claude, Gemini, Perplexity. Their replies routinely contain $...$ for math. The renderer underneath is almost always KaTeX — fast, tiny bundle, graceful error fallback.

Users never notice: they only see "AI math looks great." But KaTeX's download counts and CDN hits have grown an order of magnitude over two years. It is now on the critical path of the AI era.

MATHML CORE

MathML Core (W3C 2023) — a threat?

MathML Core finalised in W3C 2023; Chromium 109+ ships native support. In theory browsers can render math directly, no KaTeX needed. In practice: cross-browser visual inconsistency remains huge — Firefox / Safari / Chrome's MathML output simply doesn't match. KaTeX's HTML+CSS path is pixel-identical everywhere — that moat is good for at least five more years.

WASM TEX

SwiftLaTeX / texlive.js — different lane

Since 2020 WebAssembly TeX engines (SwiftLaTeX, tectonic-wasm) run full LaTeX in the browser: TikZ, BibTeX, PDF output, all of it. But the bundles are 20MB+, multi-second cold start — they live in a different use case from KaTeX: paper preview vs inline web math. The two don't compete.

STEADY

Steady maintenance — not decline

KaTeX no longer ships monthly, no longer chases new features. But "successful projects look like this": tight scope, low bug count, no complaints. SQLite / curl / KaTeX all belong to this category. Steady state isn't death — it's "the work is done".