Skip to content

Why Inkwell Uses Typst Instead of a Browser Print Dialog

Most markdown editors make a PDF the same way: they render your document as HTML, then print that HTML through a headless browser and save the result. It is the path of least resistance. The preview is already HTML, the browser is already there, and print-to-PDF is a single function call.

It also produces documents that look like a web page someone flattened onto paper. Inkwell used to work this way. In version 1.4 we tore the whole thing out and replaced it with Typst, a typesetting engine written in Rust and compiled directly into the app. No browser touches your PDF anymore. This post is about why that was worth doing, and what it costs, because it does cost something.

What breaks when a browser makes your PDF

A browser is built to lay out pages that scroll. Paper does not scroll. When you force a scrolling layout engine to paginate, you inherit a specific set of problems:

  • Page breaks land in the wrong place. A heading gets stranded at the bottom of a page while its section starts on the next one. A paragraph splits across the fold with a single orphaned line left behind. The browser has no real concept of a page, so it guesses.
  • Font metrics drift. The PDF depends on whatever fonts and rendering the host system happens to provide, so the same document can come out subtly different on two machines.
  • Screen CSS gets stretched onto paper. The stylesheet was written for a glowing rectangle at arm's length. Printed, the margins, line heights, and spacing that felt right on screen read as slightly off.

None of this is a bug in any one editor. It is what happens when the tool that lays out the document was designed for a different medium.

What Typst is, and why a typesetting engine is different

Typst is not a browser and not a wrapper around one. It is a typesetting engine, in the lineage of TeX, built from scratch for laying out documents that will become pages. It understands things a browser does not have first-class concepts for: baselines, page grids, line-breaking as a paragraph-level optimization, keeping a heading with the text that follows it.

Because it is native Rust, we compile it straight into the Inkwell binary. That has three consequences that matter:

  • No browser dependency. The PDF pipeline does not spin up a rendering engine or reach for a system print path. It is just code inside the app.
  • The same output everywhere. Windows, macOS, and Linux run the identical engine over the identical document, so a PDF made on one is the PDF made on any of them.
  • It runs fully offline. PDF export makes no network calls at all. Nothing about generating your document leaves your machine.

We also embed Inkwell's own fonts rather than depending on whatever the operating system has installed. The document is set in the same typographic family the editor uses, so what you export carries Inkwell's identity instead of the host system's defaults. That is why two people on two different computers get the same page.

How your markdown becomes a typeset document

Under the hood, Inkwell treats the conversion as a compiler with a defined target, not a best-effort scrape of the preview. Your markdown is compiled into Typst markup, Typst lays that out, and the result is a PDF.

Treating it as a compiler is a deliberate choice, and an honest one. A compiler has a defined input language and a defined subset it knows how to translate. Inkwell handles the constructs that matter for writing: headings with a real hierarchy, body text, code blocks in a monospace face, and chapter breaks, where every ## heading starts a fresh page so a manuscript reads like chapters instead of a scroll. Math written for KaTeX passes through, since KaTeX and Typst speak largely compatible math. Mermaid diagrams are pre-rendered to vector SVG and embedded, so they print crisp at any size instead of pixelating.

For the curious, there is a debug command that exports the intermediate Typst source, so you can see exactly what your document compiled to before it became a PDF.

The honest tradeoff

A typesetting engine gives you good defaults. It does not give you arbitrary control, and pretending otherwise would be dishonest.

The PDF layout is opinionated. You do not get to drop in arbitrary CSS and rearrange the page, because there is no browser to accept CSS. You get a clean, readable document with sensible typography, and today you take it largely as it comes. Custom templates, so you can define your own document styling, are on the roadmap rather than in your hands right now. And because the converter targets a defined subset, an exotic construct at the edge of markdown may not have a mapping.

That is the trade: you give up fiddly per-document control, and in return every document you export is typeset properly, looks the same on every machine, and never depended on a browser to produce. For a writing tool, we think that is the right side of the bargain. Typography is the whole point of turning writing into a PDF. If the output looked like a printed web page, there would be little reason to leave the editor at all.

Where this lives

PDF export is part of Inkwell Pro, a one-time $19 license that also covers standalone HTML export. Like the rest of Inkwell, once you own it, it works offline and keeps working with no server to check in with. The full feature detail is on the Exports page.