Typst math, in the browser.
npm install kern-typ
pnpm add kern-typ
The npm package is kern-typ because kern was already
registered. The UMD global, CSS prefix, and everything else is still
kern.
Via CDN (jsDelivr):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kern-typ/styles/kern.css">
<script src="https://cdn.jsdelivr.net/npm/kern-typ/dist/kern.min.js"></script>
Via unpkg:
<script src="https://unpkg.com/kern-typ/dist/kern.min.js"></script>
import { render, renderToString } from 'kern-typ';
// Render into a DOM element
render('frac(a, b)', document.getElementById('math'));
// Render to string (for SSR or innerHTML)
const html = renderToString('x^2 + y^2 = r^2');
document.getElementById('math').innerHTML = html;
UMD (script tag):
<script src="https://cdn.jsdelivr.net/npm/kern-typ/dist/kern.min.js"></script>
<script>
kern.render('e^(i pi) + 1 = 0', document.getElementById('math'));
</script>
render(source, element, options?)
Renders Typst math source into element, replacing its
contents. Throws ParseError on invalid input unless
throwOnError: false.
kern.render('sum_(i=0)^n i^2', el);
kern.render('frac(x, y)', el, { displayMode: true });
renderToString(source, options?)Returns the rendered HTML string without touching the DOM.
const html = kern.renderToString('alpha + beta = gamma', {
output: 'mathml',
displayMode: false,
});
| Option | Type | Default | Description |
|---|---|---|---|
displayMode |
boolean |
false |
Block (display) vs. inline rendering |
output |
'mathml' | 'html' | 'htmlAndMathml' |
'mathml' |
Output format |
throwOnError |
boolean |
true |
Throw ParseError on invalid input |
errorColor |
string |
'#cc0000' |
Error message color when throwOnError is false |
macros |
Record<string, string> |
{} |
Custom macro definitions |
strict |
boolean | 'ignore' | 'warn' | 'error' |
'warn' |
Strictness level for unrecognized input |
trust |
boolean | function |
false |
Trust level for security-sensitive features |
Automatically find and render all math delimiters in a DOM subtree. Same interface as KaTeX's auto-render extension.
import renderMathInElement from 'kern-typ/auto-render';
renderMathInElement(document.body, {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false },
{ left: '\\[', right: '\\]', display: true },
{ left: '\\(', right: '\\)', display: false },
],
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
errorCallback: (msg, err) => console.warn(msg, err),
});
| Option | Description |
|---|---|
delimiters |
Array of { left, right, display } objects |
ignoredTags |
Tag names whose content is skipped |
ignoredClasses |
Elements with these classes are skipped |
errorCallback |
Called with (message, error) on parse failure |
preProcess |
Transform math string before rendering |
output: 'mathml' (default) emits a native <math>
element. All major browsers support MathML as of 2023. This is the recommended mode.
output: 'html' emits a span tree using kern-* CSS classes,
styled by kern.css. Useful for environments that don't support MathML
(older webviews, PDF renderers).
output: 'htmlAndMathml' emits both: the HTML tree is aria-hidden and the
MathML element provides accessible semantics.
kern throws a ParseError (subclass of Error) with two extra
fields: position (byte offset in the source string) and
source (the original input).
import { ParseError } from 'kern-typ';
try {
kern.renderToString('frac(x,');
} catch (e) {
if (e instanceof ParseError) {
console.log(e.position); // offset of the unexpected token
console.log(e.source); // the original input string
}
}
Set throwOnError: false to render a styled error span instead of
throwing.
kern's API is intentionally identical to KaTeX's. The only changes are the import name and the math source syntax.
| KaTeX | kern |
|---|---|
katex.render(src, el) |
kern.render(src, el) |
\frac{a}{b} |
frac(a, b) |
\sqrt{x} |
sqrt(x) |
x_{n+1} |
x_(n+1) |
\hat{f} |
hat(f) |
\mathbf{x} |
bold(x) |
\mathcal{A} |
cal(A) |
\mathbb{R} |
bb(R) |
\text{hello} |
"hello" |
\alpha, \beta |
alpha, beta |
\infty |
infinity |
Each example is rendered live by kern:
For Typst visual parity, include kern-newcm.css after kern.css.
It loads New Computer Modern Math (Typst's default math font) from
fred-wang/MathFonts
via jsDelivr:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kern-typ/styles/kern.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kern-typ/styles/kern-newcm.css">
For MathML output, the browser uses its system math font by default. Add this to your CSS to use New Computer Modern Math for MathML elements too:
@font-face {
font-family: 'NewCMMath-Regular';
src: url('https://cdn.jsdelivr.net/gh/fred-wang/MathFonts@master/NewComputerModern/fonts/NewCMMath-Regular.woff2') format('woff2'),
url('https://cdn.jsdelivr.net/gh/fred-wang/MathFonts@master/NewComputerModern/fonts/NewCMMath-Regular.woff') format('woff');
}
math {
font-family: 'NewCMMath-Regular', 'New Computer Modern Math', serif;
}