The @streamdown/math plugin renders mathematical expressions using KaTeX. It wires remark-math (parsing) and rehype-katex (rendering) into the Streamdown pipeline and produces accessible MathML output alongside the visual representation.
Installation
Install the packages
npm install @streamdown/math
KaTeX is a dependency of @streamdown/math and will be installed automatically. You do not need to install it separately.
Import the KaTeX stylesheet
KaTeX requires its CSS to render correctly. Import it once at the root of your application:import 'katex/dist/katex.min.css';
Without this import, math expressions will render without proper spacing, sizing, and symbol fonts. Pass the plugin to Streamdown
import { Streamdown } from 'streamdown';
import { math } from '@streamdown/math';
import 'katex/dist/katex.min.css';
export default function Chat({ markdown }: { markdown: string }) {
return (
<Streamdown plugins={{ math }}>
{markdown}
</Streamdown>
);
}
Math syntax
Block math
Surround an expression with $$ on its own lines to render a centered, display-style equation:
$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
Inline math
By default, $$...$$ on a single line renders inline:
The quadratic formula is $$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ for any quadratic equation.
Single-dollar syntax
Single $...$ delimiters are disabled by default to avoid conflicts with currency symbols. Enable them explicitly:
import { createMathPlugin } from '@streamdown/math';
const math = createMathPlugin({
singleDollarTextMath: true,
});
Enabling singleDollarTextMath will cause any $ in your content to be treated as a potential math delimiter, which may break currency formatting. Use with caution in user-generated content.
Configuration
createMathPlugin(options?)
interface MathPluginOptions {
/**
* KaTeX error color
* @default "var(--color-muted-foreground)"
*/
errorColor?: string;
/**
* Enable single dollar sign for inline math ($...$)
* @default false
*/
singleDollarTextMath?: boolean;
}
import { createMathPlugin } from '@streamdown/math';
const math = createMathPlugin({
singleDollarTextMath: false, // default
errorColor: '#dc2626', // red error highlight
});
API reference
MathPlugin
interface MathPlugin {
name: 'katex';
type: 'math';
remarkPlugin: Pluggable; // remark-math
rehypePlugin: Pluggable; // rehype-katex
getStyles?: () => string;
}
getStyles()
Returns the path to the KaTeX CSS file for programmatic use:
import { math } from '@streamdown/math';
const cssPath = math.getStyles?.();
// Returns: "katex/dist/katex.min.css"
This is useful if you need to dynamically inject the stylesheet or reference the path in a build tool.
@streamdown/math exports a pre-configured instance with default options:
import { math } from '@streamdown/math';
// Equivalent to: createMathPlugin()
Common examples
Fractions
$$\frac{numerator}{denominator}$$
Square roots
$$\sqrt{x}$$ or $$\sqrt[n]{x}$$
Summations
$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$
Matrices
$$
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
$$
Greek letters
$$\alpha, \beta, \gamma, \delta, \pi, \sigma, \omega$$
Escaping backslashes
In JavaScript/TypeScript string literals, backslashes must be escaped:
// Incorrect — \f is not a valid escape sequence
const markdown = "$\frac{1}{2}$";
// Correct — double-escape the backslash
const markdown = "$$\\frac{1}{2}$$";
// Correct — template literals handle single backslashes
const markdown = `$$\frac{1}{2}$$`;