Mathematics
Render beautiful LaTeX equations with KaTeX support in Streamdown.
Streamdown provides built-in support for rendering mathematical expressions using LaTeX syntax, powered by KaTeX. Write complex equations and formulas that render beautifully alongside your content.
Enabling Math
Math rendering requires the math plugin. Install it:
npm install @streamdown/mathThen import and pass the plugin to Streamdown:
import { Streamdown } from "streamdown";
import { math } from "@streamdown/math";
import "katex/dist/katex.min.css";
export default function Page() {
return (
<Streamdown plugins={{ math: math }}>
{markdown}
</Streamdown>
);
}Syntax
Streamdown uses double dollar signs ($$) to delimit mathematical expressions. Unlike traditional LaTeX, single dollar signs ($) are not used to avoid conflicts with currency symbols in regular text.
Inline Math
Wrap inline mathematical expressions with $$:
The quadratic formula is $$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ for solving equations.Renders as: The quadratic formula is for solving equations.
Block Math
For display-style equations, place $$ delimiters on separate lines:
$$
E = mc^2
$$This renders the equation centered and larger:
Common Mathematical Expressions
Fractions
$$\frac{numerator}{denominator}$$Example: ,
Square Roots
$$\sqrt{x}$$ or $$\sqrt[n]{x}$$Example: ,
Exponents and Subscripts
$$x^2$$ or $$x_i$$ or $$x_i^2$$Example: ,
Greek Letters
$$\alpha, \beta, \gamma, \delta, \theta, \pi, \sigma, \omega$$
$$\Gamma, \Delta, \Theta, \Pi, \Sigma, \Omega$$Common letters:
Summations
$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$The sum of first natural numbers:
Integrals
$$\int_{a}^{b} f(x) \, dx$$Definite integral:
Limits
$$\lim_{x \to \infty} \frac{1}{x} = 0$$Example:
Matrices
$$
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
$$A 2×2 matrix:
Advanced Examples
The Quadratic Formula
$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$Euler's Identity
$$
e^{i\pi} + 1 = 0
$$Normal Distribution
$$
f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2}
$$The probability density function:
Taylor Series
$$
e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots
$$Integration by Parts
$$
\int u \, dv = uv - \int v \, du
$$Special Operators and Symbols
Comparison Operators
$$\leq$$ $$\geq$$ $$\neq$$ $$\approx$$ $$\equiv$$, , , ,
Set Notation
$$\in$$ $$\notin$$ $$\subset$$ $$\subseteq$$ $$\cup$$ $$\cap$$ $$\emptyset$$, , , , ,
Logic Symbols
$$\land$$ $$\lor$$ $$\neg$$ $$\implies$$ $$\iff$$ $$\forall$$ $$\exists$$, , , , , ,
Calculus Notation
$$\frac{dy}{dx}$$ $$\frac{\partial f}{\partial x}$$ $$\nabla$$ $$\infty$$Derivative: , Partial: , Gradient: , Infinity:
Configuration
Custom Error Color
Customize how errors are displayed using createMathPlugin:
import { Streamdown } from 'streamdown';
import { createMathPlugin } from '@streamdown/math';
import 'katex/dist/katex.min.css';
const math = createMathPlugin({
errorColor: '#dc2626',
});
export default function Page() {
return (
<Streamdown plugins={{ math }}>
{markdown}
</Streamdown>
);
}Complete Configuration Example
import { Streamdown } from 'streamdown';
import { createMathPlugin } from '@streamdown/math';
import 'katex/dist/katex.min.css';
const math = createMathPlugin({
singleDollarTextMath: true, // Enable $...$ syntax (default: false)
errorColor: '#dc2626', // Custom error color (default: "var(--color-muted-foreground)")
});
export default function Page() {
return (
<Streamdown plugins={{ math }}>
{markdown}
</Streamdown>
);
}Disable Math Support
If you don't need math support, you can exclude the plugins:
import { Streamdown } from 'streamdown';
export default function Page() {
return (
<Streamdown
remarkPlugins={[]} // Removes remark-math
rehypePlugins={[]} // Removes rehype-katex
>
{markdown}
</Streamdown>
);
}Note: This will remove all default plugins, so you'll need to add back any others you need.
Streaming Considerations
Incomplete Equations
Streamdown's unterminated block parser handles incomplete equations gracefully:
$$
E = mc^During streaming, the parser detects the incomplete block-level equation and adds the closing $$ delimiter, ensuring proper rendering even before the equation is complete.
Inline vs Block Detection
The parser distinguishes between inline and block math:
- Inline: (same line)
- Block: Separate lines with newlines
This is inline $$E = mc^2$$ math.
$$
E = mc^2
$$
This is block math.Accessibility
Mathematical expressions rendered by KaTeX include:
- MathML - Machine-readable math representation
- Title Attributes - LaTeX source in tooltips
- Semantic HTML - Proper structure for screen readers
- Scalable Typography - Math scales with text size settings
Performance
KaTeX is chosen for its performance characteristics:
- Fast Rendering - 2-3x faster than MathJax
- No JavaScript Runtime - Pure CSS styling (after initial render)
- Small Bundle - Minimal impact on page load
- Cached Parsing - Streamdown memoizes rendered equations
Common Issues
Escaping Backslashes
In JavaScript/TypeScript strings, backslashes need to be escaped:
// ❌ Wrong
const markdown = "$\frac{1}{2}$";
// ✅ Correct
const markdown = "$$\\frac{1}{2}$$";
// ✅ Or use template literals
const markdown = `$$\frac{1}{2}$$`;Currency vs Math
Streamdown uses $$ for math to avoid conflicts with currency:
This item costs $5 and that one costs $10. (These are currency symbols)
This equation $$x = 5$$ is mathematical notation. (This is math)Spacing in Equations
Use \, for thin space, \: for medium space, \; for thick space:
$$\int f(x) \, dx$$Better spacing:
Resources
- KaTeX Documentation - Complete list of supported functions
- KaTeX Support Table - Feature compatibility
- LaTeX Math Symbols - Symbol reference
Plugin Interface
The Math plugin implements the MathPlugin interface:
interface MathPlugin {
name: "katex";
type: "math";
remarkPlugin: Pluggable; // remark-math for parsing
rehypePlugin: Pluggable; // rehype-katex for rendering
getStyles?: () => string; // Returns "katex/dist/katex.min.css"
}Use getStyles() to get the CSS path programmatically:
import { math } from '@streamdown/math';
const cssPath = math.getStyles?.();
// "katex/dist/katex.min.css"Best Practices
Keep Equations Readable
Break complex equations into steps:
Start with the equation:
$$
f(x) = ax^2 + bx + c
$$
Complete the square:
$$
f(x) = a\left(x + \frac{b}{2a}\right)^2 + c - \frac{b^2}{4a}
$$Add Context
Explain your equations:
The Pythagorean theorem states that for a right triangle:
$$
a^2 + b^2 = c^2
$$
where $$a$$ and $$b$$ are the legs and $$c$$ is the hypotenuse.Use Block Math for Complex Expressions
Reserve inline math for simple expressions:
✅ Good: The slope is $$m = \frac{y_2 - y_1}{x_2 - x_1}$$
❌ Avoid: $$\int_{-\infty}^{\infty} e^{-x^2} \, dx = \sqrt{\pi}$$ in the middle of text
✅ Better:
$$
\int_{-\infty}^{\infty} e^{-x^2} \, dx = \sqrt{\pi}
$$Related Features
- Typography - Text styling that complements mathematical content
- Unterminated Block Parsing - How streaming works with equations
- GitHub Flavored Markdown - Extended Markdown features