Platex

A published npm package, CLI, and edge-compatible microservice that compiles LaTeX to PDF from any framework speaking the Fetch API - 100% test coverage, CI-enforced.

I keep reaching for LaTeX to generate PDFs from code - resumes, invoices, reports - and every time I do, I’m re-solving the same problem: how do I run a full TeX toolchain somewhere that isn’t my laptop, ideally without provisioning a server just to run pdflatex. So I built @nandan-varma/platex: a package, a CLI, and a compile service that all share one engine.

One client, every framework

createPlatexClient() gives you a .compile() call from app code. handleCompileRequest is a drop-in route handler with the same signature in Next.js, TanStack Start, Astro, SvelteKit, and Remix - copy the recipe, done. There’s also a standalone CLI, npx @nandan-varma/platex main.tex, for compiling without any of that.

Underneath, the library picks the right engine automatically: if a serviceUrl is configured it compiles remotely via Tectonic; if system TeX is present it shells out to pdflatex/xelatex/lualatex; if neither, it falls back to a bundled Tectonic binary. Callers never configure which path they’re on.

Tectonic, and why it matters for the edge

Tectonic is a self-contained XeTeX engine that auto-downloads missing LaTeX packages from its own CDN and handles multi-pass compilation and bibliographies without a manual bibtex step. That self-containment is what makes the edge-runtime build possible at all - the compile service is verified in CI to ship zero node: imports, so it runs on Vercel’s edge runtime and Cloudflare Workers, not just a Node server.

Hardening and coverage

Compiling arbitrary user-supplied LaTeX is an invitation for resource exhaustion and path traversal if you’re not careful, so I added explicit timeout budgets, resource-exhaustion limits, and path-traversal/integrity fixes on top of the compile pipeline - then drove the test suite to 100% coverage and made that a CI gate, not an aspiration. A single-pass log parser (replacing an earlier multi-pass one) cut hot-path latency roughly 100x on log unwrapping, which matters on warm serverless containers where the compile loop runs repeatedly.

Key decisions

Built with