npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@simonklee/opentui-tex

v0.3.1

Published

TeX renderable with Unicode and native image backends for OpenTUI

Readme

OpenTUI TeX

OpenTUI TeX renders TeX math in a standard OpenTUI renderable tree:

import { TexRenderable, UnicodeTexBackend } from "@simonklee/opentui-tex";

container.add(
  new TexRenderable(renderer, {
    formula: String.raw`\sum_{i=1}^{n} i^2`,
    display: true,
    foreground: "#ffffff",
    background: "#000000",
    backend: new UnicodeTexBackend(),
  }),
);

The terminal shows selectable text cells:

  n
  ∑   i²
i = 1

One package supplies two output types:

  • @simonklee/opentui-tex renders formulas as semantic Unicode cells without loading the TeX native library.
  • @simonklee/opentui-tex/native renders formulas as images (Kitty, Sixel, or block cells) through a prebuilt shared library.

Both backends run on Bun and Node. On Node, native rendering requires version 26.4 or newer and experimental foreign function interface (FFI) flags. See Images.

Install

For npm releases from 0.2.0 onward, install one package:

npm install @simonklee/opentui-tex

You can also use bun add.

Like @opentui/core, the package uses optional dependencies to select a prebuilt library for the host platform. You do not need a local native build. Prebuilt libraries exist for x64 and arm64 on macOS, Windows, Linux glibc 2.17, and Linux musl. On Linux, Bun 1.3.14 installs both libc variants. The loader selects one at runtime.

@opentui/core is a required peer dependency, not a bundled copy. Use the same version across your application and its OpenTUI bindings. This release requires 0.0.0-20260812-1d34234c. Compatibility with other Core versions is not yet verified. npm installs required peers automatically.

The JavaScript package is MIT-licensed. The optional native binaries are GPL-3.0-only because they link ZigTeX. Each binary package includes its license notices. Before you redistribute native rendering, review those licenses.

@simonklee/opentui-tex-native-source contains the corresponding source at the same version. The source package is not a runtime dependency.

To upgrade from the 0.1.0 GitHub tarballs, replace imports from @simonklee/opentui-tex-native with @simonklee/opentui-tex/native. Then remove the separate native dependency. The existing 0.1.0 release assets are unchanged.

TexRenderable

TexRenderable is the primary application component. It is a backend-neutral BoxRenderable, not an image subclass. You must select a backend:

const formula = new TexRenderable(renderer, {
  formula: String.raw`\frac{-b \pm \sqrt{b^2-4ac}}{2a}`,
  display: true,
  foreground: "#ffffff",
  background: "#000000",
  widthMax: 60,
  heightMax: 12,
  backend: new UnicodeTexBackend(),
  fallback: "unicode",
});

container.add(formula);

Options beyond BoxOptions:

  • formula (required): TeX source, at most 4,096 UTF-8 bytes.
  • foreground, background (required): six-digit hexadecimal colors (#rrggbb).
  • backend (required): the TexBackend that renders the formula.
  • display: display style instead of inline style. The default is false.
  • widthMax, heightMax: output limits in cells. The defaults are 80 and 24.
  • fallback: behavior after a failure. The default is "message".
  • streaming: preview updates for incomplete input. The default is false.
  • strict: reject unsupported Unicode commands and delimiters instead of showing their names as text. This check also applies to previews. The default is false.
  • imageOptions: options for the installed ImageRenderable.
  • onError: receives backend errors.

Automatic width and height include borders and padding. Explicit dimensions set the outer box size. Unicode output clips to the available cells without wrapping mathematical rows.

When you assign to formula.formula, TexRenderable installs synchronous Unicode output. With the built-in Unicode backend, this is the final result. Other backends run next. A native result replaces the preview with an image in the same TexRenderable.

formula.whenReady() tracks replacement requests. It resolves after TexRenderable installs the latest result. formula.ready exposes the current request. setColors() renders the formula again after a terminal theme change. TexRenderable aborts requests for stale or destroyed nodes.

With streaming: true, only the synchronous Unicode preview changes. The layout shows incomplete constructs at the end of the input as placeholders.

The fallback option controls behavior after a failure:

  • "unicode" keeps the semantic preview.
  • "retain" restores the previous successful backend result.
  • "message" displays an error. This is the default.
  • "throw" rejects readiness.

Share one backend across multiple TexRenderable instances.

A TexBackend transfers ownership of each image output to the receiver. The receiver must dispose the image. TexRenderable manages all images that its backend returns, including stale outputs and outputs that the "retain" fallback keeps. Thus, most applications do not manage images directly.

React and Solid

Use the same registration pattern as other OpenTUI extension packages:

import { registerTex } from "@simonklee/opentui-tex/react"; // or @simonklee/opentui-tex/solid

registerTex();

registerTex() registers a <tex> component. Its reactive props are formula, streaming, display, foreground, and background. The component passes the other TexRenderable options without changes:

<tex
  formula={String.raw`e^{i\pi} + 1 = 0`}
  foreground="#ffffff"
  background="#000000"
  backend={backend}
/>

@opentui/react and @opentui/solid are optional peer dependencies. Install the one that matches your renderer.

Backends

A TexBackend returns an owned NativeImage or semantic Unicode text. The Unicode backend installs a TextRenderable. The native backend installs an ImageRenderable.

Unicode cells

UnicodeTexBackend parses a bounded subset of TeX math into an abstract syntax tree. It arranges fractions, roots, scripts, accents, aligned equations, matrices, cases, and annotated braces as two-dimensional terminal cells. Arrays support l, c, r, and vertical rules. Continued fractions accept [l] and [r]. Font commands preserve bold and italic attributes or select Unicode mathematical alphabets.

The output remains selectable terminal text. string-width measures the output. The backend is stateless and synchronous, and renderSync is public. It needs no cache or explicit destruction.

To distinguish supported math from source that should remain unrendered, use strict: true:

const output = new UnicodeTexBackend().renderSync({
  formula: String.raw`\mathbb{R} + \mathbf{x}`,
  display: true,
  foreground: "#ffffff",
  background: "#000000",
  widthMax: 80,
  heightMax: 24,
  strict: true,
  signal: new AbortController().signal,
});

The Unicode backend accepts at most 4,096 UTF-8 source bytes and limits each layout box to 16,384 cells before clipping. It does not compile LaTeX documents or load user-defined TeX packages.

Images

Import the native backend explicitly. The package root of @simonklee/opentui-tex never loads native code. The platform shared library loads during the first native render:

import { NativeTexBackend } from "@simonklee/opentui-tex/native";

const backend = new NativeTexBackend();

On Linux musl, set OPENTUI_LIBC=musl before you start the application. This setting makes OpenTUI and TeX select musl libraries. See Native rendering for library overrides and standalone executables.

MicroTeX parses a TeX-math dialect and computes glyph and rule positions. ZigTeX records Scalable Vector Graphics (SVG) paths for the embedded glyph outlines from Latin Modern Math. NanoSVG rasterizes only the SVG that ZigTeX generates. It does not rasterize arbitrary external SVG.

MicroTeX uses one process-wide font context. The native library initializes this context once through texInit. It keeps the context for the process lifetime.

The renderer supports only the main JavaScript thread. If you construct NativeTexRenderer in a Worker, the constructor fails immediately.

Ownership rules for direct use:

  • If you call NativeTexRenderer.renderAsync() directly, you must dispose each returned image. Cached results use independent retained references. When you dispose one result, the other results stay valid.
  • NativeImage.takeRaw() requires exclusive ownership. Before you call it, dispose all retained references. These include references that the renderer cache and renderables hold.

Custom backends

TexBackend is a public interface with one method:

interface TexBackend {
  render(request: TexRenderRequest): Promise<TexRenderOutput>;
}

The request contains formula, display, foreground, background, widthMax, heightMax, an AbortSignal, and optional strict validation for Unicode math. The output is either { kind: "image", image } or { kind: "unicode", text, columns, rows }.

Unicode output can also include spans, an array of { text, color?, bold?, italic? } objects. The concatenated span text equals text. TexRenderable uses these spans to preserve styling. Plain-text consumers can continue to read text.

Node

Native rendering requires Node 26.4 or newer. Start Node with these options:

node --permission --allow-fs-read=<application> --allow-ffi --experimental-ffi app.js

Development

You can develop the package without the native toolchain.

bun run test
bun run typecheck
bun run build:package

Native builds require Zig 0.16.0 and curl. Use this command to test a native build:

bun run test:native

For npm authentication, release checks, and publishing, see Releasing.