LaTeX.js: a LaTeX to HTML5 translator that stays in the browser
JavaScript LaTeX to HTML5 translator
At a glance
- What is it?
- LaTeX.js parses LaTeX with a PEG grammar and emits HTML5 plus CSS in the shape of TeX output, with no server side round trip. It is built for rendering math on the web, and it carries the limits of any parser that tries to match TeX closely rather than approximately.
- Who is it for?
- LaTeX.js fits a team that wants LaTeX math and simple documents rendered to HTML5 on the client, with npm install latex.js as the whole setup, and it does not fit a publishing pipeline that needs the full TeX macro system or typesetting fidelity that only a real TeX engine can give you.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A PEG grammar parses LaTeX into HTML5, with CSS imitating TeX output
The design bet of this project is that a LaTeX subset can be parsed accurately enough in a browser to render documents and formulas without a server. The README states the ambition plainly: LaTeX.js tries to be absolutely and uncompromisingly exact and compatible with LaTeX, and the generated HTML is meant to be exactly what would be output, down to the last space.
The parsing machinery is PEG.js, and the repository keywords list pegjs and peggy, which suggests the grammar tooling moved from PEG.js toward its successor. The source lives in src/ with a TypeScript configuration in tsconfig.json and a Vite build in vite.config.ts, and the shipped artefacts are assembled by a build script that copies CSS, fonts and document class files into dist/.
The package publishes several entry points for different consumers. The exports map points an import to ./dist/latex.js and a require to ./dist/latex.cjs, with type definitions at ./dist/latex.d.ts, and a browser field pointing at ./dist/latex.umd.cjs. A bin entry named latex.js points at ./bin/latex.js, so the same package serves as a command line tool and as a library.
The font handling is worth noting because it is the part that most affects fidelity. The build copies fonts from public/fonts/ and also copies woff2 files out of the node_modules/katex/dist/fonts directory, which is a pragmatic way to get a workable math font set without vendoring every glyph file by hand.
npm install is the entire setup, and the playground is the fastest proof
There is no build step for the consumer and no service to stand up. For command line use the README gives a global install:
npm install -g latex.jsFor library use it goes into a project as a production dependency:
npm install --save-prod latex.jsThat is the entire installation story, and the difference between the two forms is where the CLI entry comes from. The bin entry in package.json maps the command latex.js to ./bin/latex.js, so a global install gives you an executable that translates a file, while the library form gives you the same translation as a function you call in your own build.
The fastest way to see whether the output matches your expectations is the playground at latex.js.org/playground.html, linked from the README. For a project that renders user supplied math, this matters: you can paste a document, look at the resulting HTML, and check the spacing before wiring anything into a production path.
The published package version is 0.12.6, and the dist directory in the files list is prebuilt during release rather than compiled on install. The repository also carries docs/, public/, lib/, test/ and a package-lock.json, so the build is reproducible from a lockfile and the test suite runs under mocha.
Where HTML and TeX disagree, the README points at the ceiling
The project is explicit that exact TeX behaviour is not always reachable in HTML, and it links to a limitations section for the cases where it is impossible in principle rather than merely unimplemented. That framing is the honest description of the project.
The reason is structural. TeX's output model is a page of boxes placed with precise glue, kerning and rules, and it depends on a font metric set and a line breaking algorithm that HTML does not offer. The CSS shipped with the project makes the result look like LaTeX output, and the README says so with an explicit exception for the impossible cases. If your requirement is a document that matches a PDF byte for byte, no amount of parser accuracy changes that, because the target format is different.
There is a related scope question about what LaTeX means here. A LaTeX document is a program in the TeX language, and much of what people mean by LaTeX is macro packages and document classes. The package files in the dist directory, listed under dist/packages/ and dist/documentclasses/, show that some of this is bundled, but the repository does not claim to be a complete TeX distribution, and it does not run a TeX engine.
So the practical boundary is this: LaTeX.js is a translator for content that LaTeX can express in a way a parser can model, which covers a great deal of mathematics and a reasonable range of document markup, and it does not attempt to be a typesetter.
TeX4ht, LaTeXML and LaTeX2HTML take the other route entirely
The README lists the alternatives and says plainly what the difference is. Each of TeX4ht, LaTeXML and LaTeX2HTML understands TeX to some extent, and each of them is written outside JavaScript: TeX4ht in TeX, LaTeXML in Perl, LaTeX2HTML in Perl. Two more entries, HEVEA and plasTeX, are struck through in the list, with the comment that they are nowhere near the quality of LaTeX.js.
The difference in approach is the point. Those tools drive or wrap a real TeX installation, so they inherit TeX's macro expansion, its package system and its typesetting fidelity, and they need a TeX distribution present on the machine. LaTeX.js takes the opposite approach: it parses the source directly with a PEG grammar and produces HTML5 without any TeX engine, which is what allows it to run in a browser and in a JavaScript build step.
That trade-off shows up in the two directions. LaTeX.js gains deployment simplicity and browser execution, and gives up the completeness of the TeX ecosystem. The TeX based tools give up the ability to run client side, and keep the fidelity.
The README also notes that there is no such alternative in JavaScript yet, which is the stated reason the author started the project, with the motivating use case being a derby-entities-lib project of his own. So the competitive position is a niche one rather than a general replacement for TeX4ht.
A 2023 release with commits continuing into 2026
The repository is not archived and the last push was on 2026-10-13, so work has continued well past the newest release. The published tags are older: v0.12.6, described as bugfixes, on 2023-04-23, preceded by v0.12.4 on 2020-06-07 and v0.12.2 on 2020-06-06.
That gap between the working tree and the published package is the practical upgrade question. A project that installs latex.js from npm gets 0.12.6, not the current state of master, and the README does not describe a nightly or prerelease channel to bridge that. The same gap explains why the package.json version field reads 0.12.6 while the build tooling in the repository, with Vite and the modern exports map, is clearly newer than the 2023 tag.
The 0.x version number is itself a signal. A project at 0.12.x has not committed to a stable API surface, so upgrading across minor versions is a reasonable thing to expect to break something, and there is no changelog policy or compatibility promise stated in the README.
The licence is MIT, with the copyright line reading Michael Brade for 2015 to 2021. The MIT terms place no copyleft obligation on code you produce with the translator, and the licence does not restrict use in a commercial or hosted product.
The wrong tool for a publishing pipeline or a strict fidelity requirement
There are two clear cases where choosing this library leads to a bad outcome. The first is a publishing workflow that needs the real TeX ecosystem: cross references, bibliography processing, custom macro packages, or a document class you already depend on. LaTeX.js does not run a TeX engine, so anything that depends on TeX expansion semantics is out of reach, and no configuration will bring it in.
The second is a requirement for typographic equality with a TeX produced PDF. The HTML and CSS output is styled to resemble TeX, and the README is honest that some differences are impossible in principle. If a legal or academic document has to match a house template exactly, the translator approach is the wrong shape for the job.
There is a third, quieter consideration: security and untrusted input. A browser side translator that parses arbitrary text is a parser exposed to whatever an attacker can submit. The repository does not document a hardening or sandboxing policy for that case, so if you are rendering mathematics from untrusted users, you should treat the parsing path as attack surface and decide for yourself how to isolate it.
What the project is genuinely good at is narrower and still useful: getting LaTeX lookalike HTML out of a JavaScript build with no server, no TeX installation and no round trip.
Editorial conclusion
LaTeX.js fits a team that wants LaTeX math and simple documents rendered to HTML5 on the client, with npm install latex.js as the whole setup, and it does not fit a publishing pipeline that needs the full TeX macro system or typesetting fidelity that only a real TeX engine can give you. Before you commit, read the limitations section on the project site, because the README itself points at cases that are impossible in principle in HTML, and check the published version, since the newest release is v0.12.6 from 2023-04-23 while the last push was on 2026-10-13, meaning the working tree and the packaged release are not the same thing.
Frequently asked questions
How do I install LaTeX.js for use in a JavaScript project?
Run npm install --save-prod latex.js to add it as a library dependency. The package exposes import and require entry points with type definitions at ./dist/latex.d.ts. For command line use the README gives npm install -g latex.js.
Does LaTeX.js run TeX, or does it parse LaTeX itself?
It parses LaTeX itself using a PEG.js grammar and emits HTML5 plus CSS. There is no TeX engine involved, which is what allows it to run in a browser, and the README points to a limitations section for cases where HTML cannot match TeX output.
What are the alternatives to LaTeX.js?
The README lists TeX4ht, LaTeXML and LaTeX2HTML, each of which understands TeX to some extent and each written outside JavaScript. Those tools drive a real TeX installation, while LaTeX.js parses the source directly and produces HTML5.
How do I check the output before building it into a page?
The README links a playground at latex.js.org/playground.html where you can paste LaTeX and see the translated result. The repository also ships docs/ and a public/ directory with the assets used by that site.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/michael-brade-latex-js)Was this useful?