OpenTUI/math

Community package · pre-release docs

Math belongsin the terminal.

Render expressive LaTeX directly into OpenTUI's cell buffer—or switch to crisp, antialiased terminal graphics with the same component-shaped API.

bun add opentui-math @opentui/core

Reserved package name. The command becomes live with the first npm release.

  • Bun-first
  • MIT licensed
  • No TeX install
formula.tsgraphics / auto
NEW COMPUTER MODERN · 58 PXGaussian integral rendered as high-resolution terminal graphics
frame readyfallback · cells
LaTeX in\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}
01Universal cells

Baseline-aware Unicode output in every terminal.

02Kitty graphics

MathJax curves and spacing where images are supported.

03Stream safe

Coalesced deltas without parse-error flicker.

01

Renderers

Choose the right surface.

Start with the universal backend, opt into terminal graphics, or export an image without running a TUI.

Cell renderer

Works anywhere OpenTUI works.

           ╭────────
     -b ± √ b² - 4ac
x = ─────────────────
           2a
  • Native cell buffer
  • Intrinsic Yoga dimensions
  • Zero image-protocol dependency

Graphics renderer

Browser-quality curves in the terminal.

Quadratic formula rendered by the graphics backend
  • MathJax + New Computer Modern
  • Antialiased Kitty image placement
  • Automatic cell fallback

SVG or PNG, no TUI required

Use the same graphics engine for documentation, snapshots, previews, and custom composition.

Standalone image rendering
import {
  renderLatexToPng,
  renderLatexToSvg,
} from "opentui-math/graphics"

const svg = await renderLatexToSvg(String.raw`E = mc^2`)
const { png, width, height } = await renderLatexToPng(
  String.raw`E = mc^2`,
  { fontSize: 48, pixelRatio: 2 },
)
02

Quick start

A renderable in twelve lines.

The component measures itself, joins Yoga layout, and repaints whenever its content changes.

Core OpenTUI example
import { createCliRenderer } from "@opentui/core"
import { LatexRenderable } from "opentui-math"

const renderer = await createCliRenderer()
const formula = new LatexRenderable(renderer, {
  content: String.raw`x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`,
  foregroundColor: "#cdd6f4",
  displayMode: true,
})

renderer.root.add(formula)

Set graphicsMode: "auto" on GraphicalLatexRenderable when you want high-resolution output with a transparent cell fallback.

03

Examples

Real output from the package.

These assets are generated by opentui-math's MathJax and resvg graphics backend—not browser-rendered approximations.

04

Streaming

Incomplete tokens. Stable frames.

AI output rarely stops at a valid LaTeX boundary. The stream controller batches deltas, validates prefixes, and commits only the frame you intend.

Incoming LaTeX matrix tokens on the left becoming valid high-resolution rendered frames on the right

Generated from the package's graphics backend. The left side is the untouched accumulator; the right side is a temporary, structurally repaired preview.

Default

Retain

Keep the last valid formula while a new prefix is incomplete.

Transparent

Show source

Forward incomplete text to a renderable configured with source fallback.

Progressive

Repair preview

Temporarily close groups and environments without mutating the stream.

Streaming graphics example
import {
  completeLatexPrefix,
  GraphicalLatexRenderable,
  LatexStreamController,
} from "opentui-math/graphics"

const formula = new GraphicalLatexRenderable(renderer, {
  content: "",
  fallback: "source",
  graphicsMode: "auto",
})

const stream = new LatexStreamController(formula, {
  updateIntervalMs: 80,
  validationOptions: { strict: true },
  preview: completeLatexPrefix,
})

for await (const delta of latexDeltas) stream.append(delta)
await stream.finish()
05

Frameworks

Core, React, or Solid.

Use the imperative renderable directly or register one intrinsic element for your preferred reconciler.

import { createCliRenderer } from "@opentui/core"
import { LatexRenderable } from "opentui-math"

const renderer = await createCliRenderer()
const formula = new LatexRenderable(renderer, {
  content: String.raw`x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`,
  foregroundColor: "#cdd6f4",
  displayMode: true,
})

renderer.root.add(formula)
06

Reference

Small API, explicit modes.

The common path stays compact; graphics and streaming add focused controls only when you need them.

Renderable

content""
LaTeX math source
foregroundColor#e8e8f0
Formula color
displayModetrue
Limits above and below large operators
fallback"message"
Error message, source, or throw

Graphics

graphicsMode"auto"
Auto, Kitty, or cell output
fontSize32
Math size in CSS pixels
pixelRatio1
Raster output scale
graphicsZIndex1
Kitty placement stacking order

Stream

updateIntervalMs75
Quiet window for token coalescing
incompletePolicy"retain"
Retain or apply incomplete input
previewnone
Build a non-destructive temporary source
maxBufferLength100000
Bound accumulated stream input

Package map

Import only the surface you use.

Entry pointExports
opentui-mathCell renderable, pure renderer, parser, stream controller
opentui-math/graphicsKitty renderable, SVG/PNG output, graphics streaming
opentui-math/reactRegister the React <latex> intrinsic element
opentui-math/solidRegister the Solid <latex> intrinsic element
opentui-math/graphics/reactRegister the React <latexImage> element
opentui-math/graphics/solidRegister the Solid <latexImage> element
07

Syntax & runtime

Math mode, deliberately bounded.

The cell backend handles the syntax that matters for terminal math. The graphics backend accepts the TeX input supported by MathJax.

Supported

Built for expressive formulas

  • Fractions, roots, binomials, scripts, and large operators
  • Matrices, cases, arrays, aligned equations, and gathered blocks
  • Stretching delimiters, accents, text, colors, and named operators
  • Greek letters, relations, arrows, symbols, and lightweight macros

Boundary

Not a TeX distribution

It does not compile documents, execute arbitrary macros, load packages, or render TikZ. Neither backend shells out to a TeX installation.

Fallback is a feature.

Use graphicsMode: "auto". A Kitty-compatible terminal gets the raster frame; unsupported terminals and blocked multiplexers get the same formula through the universal cell renderer. Bun is the recommended runtime for OpenTUI applications.