Version 0.5.0 · LGPL-3.0

MetaPost and TikZ,
with real LaTeX

MetaPost 2.11, pdfTeX 1.40, LuaTeX 1.21 and dvisvgm 3.4 from TeX Live 2025, compiled to WebAssembly and wrapped in one small TypeScript library. MetaPost source goes in and SVG with real glyph outlines comes out; so do whole LaTeX documents, with TikZ, pgfplots and tikz-cd, one SVG per page. It runs in a web page, in a Web Worker or in Node. Nothing runs on a server.

The output is byte-identical to native TeX Live: the same C code produces it, and every deviation from upstream is a numbered, explained patch. The complete 1181-page PGF/TikZ manual typesets through the library page for page identical to latex + dvisvgm.

A pgfplots axis with two plotted functions and a legend
A tree of labelled nodes laid out by TikZ's graph-drawing library
A circle of coloured rays beneath the residue theorem
A shaded ball, a colour gradient and a crosshatch pattern
Four figures from the drop-in tags demo, typeset by the library itself and saved as SVG.

What it does

Not a reimplementation of either language, but the real programs.

The engines are the programs from TeX Live 2025, compiled to WebAssembly, so anything that typesets on a TeX installation typesets here, and the output is the same to the byte.

All of MetaPost

Every number system, boxes.mp and graph.mp, and btex … etex labels typeset by plain TeX or LaTeX — collected into a single TeX run and cached by content. Out comes SVG, the EPS mpost writes, or a JSON model of the figure.

Whole LaTeX documents

\documentclass, \usepackage, every PGF/TikZ library in TeX Live, pgfplots, tikz-cd, amsmath and Latin Modern. Shadings become gradients, patterns stay patterns, and opacity and clipping survive.

LuaTeX when it's needed

Graph drawing, \directlua and luacode switch to a second engine, LuaTeX, which is downloaded only when a document asks for it — and brings OpenType fonts with it.

A tikzjax replacement

One script tag finds <script type="text/tikz">, text/metapost, <tikz-diagram> and <metapost-diagram> elements, renders each in place, and keeps the results in IndexedDB for the next visit.

Fetched as it's needed

Fonts, macros and formats are plain static files, fetched through the real kpathsea as the engines ask for them: about 4.7 MB for a first TikZ figure, 2.3 MB for a first MetaPost one, then the browser cache.

A command line too

mpost-wasm accepts mpost's options and writes mpost's output files, takes --latex for documents, and --prerender saves a page's figures beside it, sparing first visits the engines.

Using it

On a web page, a single script tag is enough. Diagrams are written straight into the HTML, and each is replaced by its SVG:

<script type="module" src="/path/to/dist/auto.js"></script>

<script type="text/tikz" data-libraries="arrows.meta">
  \begin{tikzpicture} \draw[->,thick] (0,0) -- (2,1) node[right] {$x^2$}; \end{tikzpicture}
</script>
<script type="text/metapost">draw fullcircle scaled 50; label.top(btex $\int_0^1 x\,dx$ etex, (0,25));</script>

From JavaScript, the API returns the figures and pages directly:

import { MetaPost } from './dist/index.js';
const mp  = await MetaPost.create();
const fig = await mp.run('beginfig(1); draw fullcircle scaled 100; endfig; end.');
const doc = await mp.latex(String.raw`\documentclass[tikz]{standalone}
  \begin{document}\tikz\shade[ball color=blue!60] (0,0) circle (1);\end{document}`);
document.body.innerHTML = fig.figures[0].svg + doc.pages[0];

The feature guide covers every option, rendered by the engines themselves — among its examples a paragraph set inside a circle by TeX's \parshape, with inline TikZ pictures and displayed mathematics, which is the kind of thing a real TeX can do and a picture-only engine cannot.

Demos

Everything on these pages is rendered in your browser by the WebAssembly engines.

Get it

The prebuilt release is what most people want. Download mp-tikz-wasm-0.5.0.tar.gz or .zip from the releases page and unpack it: it holds the compiled engines, the JavaScript, the bundles and these demo pages, and needs neither TeX Live nor Emscripten.

tar xzf mp-tikz-wasm-0.5.0.tar.gz && cd mp-tikz-wasm-0.5.0
node serve.mjs 8080        # then open http://localhost:8080/site/

Host the dist/ folder on any static server — plain files, no special headers — and add the one script line to your page, or import dist/index.js. Building from source, with the twelve upstream patches each explained, is described in the repository.

Licences

mp-tikz-wasm's own code is under the LGPL-3.0. Each upstream program it builds keeps its own licence — the TeX engines and dvisvgm are distributed under the GPL — and NOTICE.md sets out what applies to what.