Files
vercel__streamdown/apps/website/content/docs/plugins/math.mdx
Hayden Bleasel 7b404379d9 Fix plugin docs
2026-03-03 13:09:00 -08:00

488 lines
9.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "@streamdown/math"
description: Render mathematical expressions using KaTeX.
type: reference
summary: KaTeX-powered LaTeX rendering for inline and block math expressions.
prerequisites:
- /docs/plugins
related:
- /docs/typography
---
The `@streamdown/math` plugin renders mathematical expressions using [KaTeX](https://katex.org/).
- Fast LaTeX rendering (2-3x faster than MathJax)
- Inline and block math support
- MathML output for accessibility
- Configurable error color and single-dollar syntax
## Install
```package-install
npm install @streamdown/math
```
## Tailwind CSS
### Tailwind v4
Add the following `@source` directive to your `globals.css` or main CSS file:
```css title="globals.css"
@source "../node_modules/@streamdown/math/dist/*.js";
```
The path must be relative from your CSS file to the `node_modules` folder containing `@streamdown/math`. In a monorepo, adjust the number of `../` segments to reach the root `node_modules`.
### Tailwind v3
Add `@streamdown/math` to your `content` array in `tailwind.config.js`:
```js title="tailwind.config.js"
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./node_modules/@streamdown/math/dist/*.js",
],
// ... rest of your config
};
```
In a monorepo, adjust the path to reach the root `node_modules`:
```js title="tailwind.config.js"
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"../../node_modules/@streamdown/math/dist/*.js",
],
// ... rest of your config
};
```
## Usage
```tsx title="chat.tsx" lineNumbers
import { math } from '@streamdown/math';
import 'katex/dist/katex.min.css';
<Streamdown plugins={{ math }}>
{markdown}
</Streamdown>
```
## Syntax
Streamdown uses double dollar signs (`$$`) to delimit mathematical expressions. Unlike traditional LaTeX, single dollar signs (`$`) are **not** used by default to avoid conflicts with currency symbols in regular text.
### Inline Math
Wrap inline mathematical expressions with `$$`:
```markdown
The quadratic formula is $$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ for solving equations.
```
Renders as: The quadratic formula is $$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ for solving equations.
### Block Math
For display-style equations, place `$$` delimiters on separate lines:
```markdown
$$
E = mc^2
$$
```
This renders the equation centered and larger:
$$
E = mc^2
$$
## Common Mathematical Expressions
### Fractions
```markdown
$$\frac{numerator}{denominator}$$
```
Example: $$\frac{1}{2}$$, $$\frac{a + b}{c - d}$$
### Square Roots
```markdown
$$\sqrt{x}$$ or $$\sqrt[n]{x}$$
```
Example: $$\sqrt{16} = 4$$, $$\sqrt[3]{27} = 3$$
### Exponents and Subscripts
```markdown
$$x^2$$ or $$x_i$$ or $$x_i^2$$
```
Example: $$a^2 + b^2 = c^2$$, $$x_1, x_2, \ldots, x_n$$
### Greek Letters
```markdown
$$\alpha, \beta, \gamma, \delta, \theta, \pi, \sigma, \omega$$
$$\Gamma, \Delta, \Theta, \Pi, \Sigma, \Omega$$
```
Common letters: $$\alpha, \beta, \gamma, \delta, \epsilon, \pi, \sigma, \phi, \omega$$
### Summations
```markdown
$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$
```
The sum of first $$n$$ natural numbers: $$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$
### Integrals
```markdown
$$\int_{a}^{b} f(x) \, dx$$
```
Definite integral: $$\int_{0}^{1} x^2 \, dx = \frac{1}{3}$$
### Limits
```markdown
$$\lim_{x \to \infty} \frac{1}{x} = 0$$
```
Example: $$\lim_{x \to 0} \frac{\sin x}{x} = 1$$
### Matrices
```markdown
$$
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
$$
```
A 2×2 matrix:
$$
\begin{bmatrix}
1 & 2 \\
3 & 4
\end{bmatrix}
$$
## Advanced Examples
### The Quadratic Formula
```markdown
$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
```
$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
### Euler's Identity
```markdown
$$
e^{i\pi} + 1 = 0
$$
```
$$
e^{i\pi} + 1 = 0
$$
### Normal Distribution
```markdown
$$
f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2}
$$
```
The probability density function:
$$
f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2}
$$
### Taylor Series
```markdown
$$
e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots
$$
```
$$
e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots
$$
### Integration by Parts
```markdown
$$
\int u \, dv = uv - \int v \, du
$$
```
$$
\int u \, dv = uv - \int v \, du
$$
## Special Operators and Symbols
### Comparison Operators
```markdown
$$\leq$$ $$\geq$$ $$\neq$$ $$\approx$$ $$\equiv$$
```
$$x \leq y$$, $$a \geq b$$, $$x \neq 0$$, $$\pi \approx 3.14$$, $$a \equiv b \pmod{n}$$
### Set Notation
```markdown
$$\in$$ $$\notin$$ $$\subset$$ $$\subseteq$$ $$\cup$$ $$\cap$$ $$\emptyset$$
```
$$x \in A$$, $$y \notin B$$, $$A \subset B$$, $$A \cup B$$, $$A \cap B$$, $$\emptyset$$
### Logic Symbols
```markdown
$$\land$$ $$\lor$$ $$\neg$$ $$\implies$$ $$\iff$$ $$\forall$$ $$\exists$$
```
$$p \land q$$, $$p \lor q$$, $$\neg p$$, $$p \implies q$$, $$p \iff q$$, $$\forall x$$, $$\exists y$$
### Calculus Notation
```markdown
$$\frac{dy}{dx}$$ $$\frac{\partial f}{\partial x}$$ $$\nabla$$ $$\infty$$
```
Derivative: $$\frac{dy}{dx}$$, Partial: $$\frac{\partial f}{\partial x}$$, Gradient: $$\nabla f$$, Infinity: $$\infty$$
## Configuration
### Custom Error Color
Customize how errors are displayed using `createMathPlugin`:
```tsx title="chat.tsx" lineNumbers
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
```tsx title="chat.tsx" lineNumbers
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>
);
}
```
### Get CSS Path
Use `getStyles()` to get the CSS path programmatically:
```tsx
import { math } from '@streamdown/math';
const cssPath = math.getStyles?.();
// "katex/dist/katex.min.css"
```
## Streaming Considerations
### Incomplete Equations
Streamdown's unterminated block parser handles incomplete equations gracefully:
```markdown
$$
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**: $$E = mc^2$$ (same line)
- **Block**: Separate lines with newlines
```markdown
This is inline $$E = mc^2$$ math.
$$
E = mc^2
$$
This is block math.
```
## Common Issues
### Escaping Backslashes
In JavaScript/TypeScript strings, backslashes need to be escaped:
```tsx
// ❌ 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:
```markdown
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:
```markdown
$$\int f(x) \, dx$$
```
Better spacing: $$\int f(x) \, dx$$
## 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
## Plugin Interface
The Math plugin implements the `MathPlugin` interface:
```tsx
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"
}
```
## Best Practices
### Keep Equations Readable
Break complex equations into steps:
```markdown
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:
```markdown
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:
```markdown
✅ 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}
$$
```
## Resources
- [KaTeX Documentation](https://katex.org/docs/supported.html) - Complete list of supported functions
- [KaTeX Support Table](https://katex.org/docs/support_table.html) - Feature compatibility
- [LaTeX Math Symbols](https://www.overleaf.com/learn/latex/List_of_Greek_letters_and_math_symbols) - Symbol reference
## Related Features
- [Typography](/docs/typography) - Text styling that complements mathematical content
- [Unterminated Block Parsing](/docs/termination) - How streaming works with equations
- [GitHub Flavored Markdown](/docs/gfm) - Extended Markdown features