Free, fast, schema-checked PDF rendering.
Publish a template with a JSON Schema. Every request is validated against it before a single glyph is typeset — then rendered in-process, with no headless browser and no per-page fees.
How it works
From template to PDF in three steps.
PostgreSQL and S3 hold every published version. Renderers stay stateless, so any replica can restart, reload, and serve the same bytes.
Publish your Typst source, fonts, static assets, and a JSON Schema as one version. Objects are content-addressed, so a published version stays exactly as you shipped it.
Validate. Each request's data is checked against the version's schema before anything compiles. Invalid input fails early, with a clear error instead of a broken PDF.
Render. Typst runs in-process and returns PDF bytes — no CLI, subprocess, shell, or headless browser in the path.
Versioned by content hash
Objects are content-addressed and checked against their manifest SHA-256. A published version renders identical bytes on every replica — indefinitely.
No headless browser
Typst runs as a Rust library in the request path. No Chromium, no subprocess, no shell to spawn — that is where the throughput comes from.
Your infrastructure, no per-page fees
Runs on the PostgreSQL and S3 you already operate. Free and open source, with templates and data that never leave your network.
Architecture
How the pieces fit together.
Quickstart
Clone it and run the whole stack.
The development Compose file starts Katagami, PostgreSQL, and MinIO with local credentials — no cloud account needed. The production Compose file runs against object storage you already operate.
Publish a template and render a PDF$ git clone https://github.com/BRO3886/katagami.git
$ cd katagami
$ docker compose -f docker-compose.dev.yml up --build -d
$ curl http://127.0.0.1:8080/v1/templates
{"templates":[]}Benchmark
No browser in the path, so renders stay cheap.
100 requests at concurrency 4, 2 CPU / 2 GiB per renderer on an 8-CPU ARM64 host, zero failures on both services. This compares a pre-published Typst template against browser-based HTML conversion for the same document — not a universal renderer claim. See the methodology for the full setup.