@jxpeng98/vitepress-typstex-vue
v1.2.0
Published
A VitePress plugin to render Typst math in Vue components, with KaTeX fallback.
Readme
vitepress-typstex-vue
A lightweight Vue plugin for VitePress sites that renders Typst expressions via the Typst wasm toolchain and falls back to KaTeX automatically. All Markdown specific behaviour has been removed – you now compose formulas explicitly with the <TypstMath> component.
Features
- 🧮 Unified component – render as inline (
:is-block="false") or display math (:is-block="true"). - ⚡ Typst wasm first – display formulas use Typst when possible for better typography.
- ♻️ Automatic fallback – LaTeX-looking content or Typst failures transparently revert to KaTeX.
- 🛡️ SSR friendly – server builds always run KaTeX only, so there is no wasm dependency on Node.
Installation
bun add -D vitepress-typstex-vue
# or pnpm add -D ...
# peer dependencies (install in your VitePress site)
pnpm add -D vitepress vue katexThis package declares several peer dependencies that must be provided by your VitePress site:
- Required:
vitepress(>= 1.6.4)vue(>= 3.5.x)katex(when using the KaTeX fallback or theclient-katexentry)
The Typst wasm toolchain is bundled as regular dependencies inside this plugin:
@myriaddreamin/typst.ts@myriaddreamin/typst-ts-renderer@myriaddreamin/typst-ts-web-compiler
You do not need to install these Typst packages yourself unless you want to share them across multiple plugins; they are resolved from this package by default.
Usage
Register the KaTeX client plugin inside .vitepress/theme/index.ts:
import DefaultTheme from 'vitepress/theme'
import type { Theme } from 'vitepress'
import typstPluginClient from 'vitepress-typstex-vue/client-katex'
import 'katex/dist/katex.min.css'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
DefaultTheme.enhanceApp?.({ app } as any)
app.use(typstPluginClient)
}
} satisfies ThemeWant MathJax instead of KaTeX for the fallback? Swap the client entry (the MathJax build lazy-loads MathJax 3’s SVG bundle from jsDelivr at runtime):
import typstPluginClient from 'vitepress-typstex-vue/client-mathjax'You can also build your own plugin instance programmatically, using:
latexEngine: switch the LaTeX renderer ('katex' | 'mathjax')fontSize: global math font size (Typst text size in pt, and LaTeX wrapper font-size in px)
import { createTypstexVuePlugin } from 'vitepress-typstex-vue'
export default {
enhanceApp({ app }) {
app.use(createTypstexVuePlugin({
latexEngine: 'mathjax', // or 'katex'
fontSize: 16 // global math font size
}))
}
}You can also import the component directly:
import { TypstMath } from 'vitepress-typstex-vue'Per-component overrides
Each <TypstMath> exposes two optional props to override the global defaults:
fontSize: per-component math size (Typst uses pt, the fallback wrapper uses px).latex-engine: choose the fallback engine for just that formula ("katex" | "mathjax").
<TypstMath src="..." :is-block="true" fontSize="20" />
<TypstMath src="..." :is-block="true" latex-engine="mathjax" />Rendering examples
Inline:
<TypstMath src="1 + 2 + 3 + \\cdots + n" :is-block="false" />Display:
<TypstMath src="\\int_0^\\infty e^{-x^2}\\,dx = \\frac{\\sqrt{\\pi}}{2}" :is-block="true" />Typst specific source is also supported:
<TypstMath src="#set math.equation(numbering: none) $ E = mc^2 $" :is-block="true" />How it works
- The component lazily loads
@myriaddreamin/typst.tsand initialises the renderer once per session. - A small heuristic (
isProbablyLatex) keeps most LaTeX-syntax inputs on the KaTeX path, saving wasm work. - Typst renders build their own mini document (
#set page(width: auto, height: auto, margin: ...)) so the SVG fits tightly. - KaTeX is used synchronously during SSR and whenever Typst fails.
Building
bun run -C packages/vitepress-typstex-vue buildThis produces dist/index.mjs (re-exports the plugin and component) and dist/client.mjs (Vue plugin entry), plus declaration files under dist/types.
