One template. Every platform. Typeset PDFs.
Oicana compiles Typst templates to PDF, PNG, and SVG from Node.js, Python, Java, C#, Rust, PHP, and the browser. No headless Chrome, no per-document fees, no document data leaving your infrastructure. One template format works everywhere.
Free for noncommercial use. Commercial use is free for 30 days, then needs a per-application subscription with unlimited seats.
- Runs in your infrastructure: PDFs are generated inside your own application. No data is sent to a third-party service.
- Multi-platform: the same template works in the browser, Node.js, C#, Java, Rust, Python, and PHP.
- Powerful layouting: templates have all of Typst, including its package ecosystem.
- Performant: a warmed up template renders a PDF in single-digit milliseconds.
- AI and version control ready: templates are text files. They live next to your code, and AI can help write them.
- No proprietary format: templates are plain Typst projects. The Typst compiler is open source.
Templates are plain Typst projects. A typst.toml manifest names the entrypoint and declares the inputs your application passes in:
[package]
name = "invoice"
version = "0.1.0"
entrypoint = "main.typ"
[tool.oicana]
manifest_version = 1
[[tool.oicana.inputs]]
type = "json"
key = "invoice"
development = "invoice.json"The entrypoint, main.typ, reads those inputs through the Oicana Typst package and lays out the document:
#import "@preview/oicana:0.2.0": setup
#let read-project-file(path) = read(path, encoding: none)
#let (input, oicana-image, oicana-config) = setup(read-project-file)
#set document(title: "Invoice", date: datetime.today())
= Invoice #input.invoice.number
Billed to: #input.invoice.customer
*Total: #input.invoice.total*The development value lets the template preview with real data in any Typst editor. oicana pack turns the directory into invoice-0.1.0.zip, the archive every Oicana integration loads.
| Platform | Package | Guide |
|---|---|---|
| Browser | @oicana/browser |
Browser / React |
| Node.js | @oicana/node |
Node.js / NestJS |
| C# | Oicana |
C# / ASP.NET |
| Java | com.oicana:oicana |
Java / Spring Boot |
| Rust | oicana |
Rust / Axum |
| Python | oicana |
Python / FastAPI |
| PHP | oicana/oicana |
PHP / Slim |
Every integration has an open source example project in the Oicana GitHub organization. The browser example is deployed at example.oicana.com.
More integrations are planned. Missing one? Open a GitHub issue or write to
hello@oicana.com. It helps us prioritize.
The getting started guide walks through creating a template, defining its inputs, and generating a PDF from any integration.
Comparing options? Read how Oicana differs from headless browsers, PDF libraries, LaTeX, and hosted APIs.
An Oicana template consists of
- one or more Typst
.typfiles - a
typst.tomlmanifest withname,version,entrypoint, andtool.oicana.manifest_version, plus any number of input definitions
Templates are ordinary Typst projects, so you can edit them in the official Typst editor or any editor with Typst support. Start from the open source example templates.
Every template sets up the Oicana Typst package. It collects the declared inputs and falls back to their default or development values:
#import "@preview/oicana:0.2.0": setup
#let read-project-file(path) = read(path, encoding: none)
#let (input, oicana-image, oicana-config) = setup(read-project-file)A template declares the standards its PDFs conform to and whether the output is tagged for accessibility:
[tool.oicana.export.pdf]
standards = ["2.0", "a-4"]
tagged = true| Family | Accepted values |
|---|---|
| Base PDF version | 1.4, 1.5, 1.6, 1.7, 2.0 |
| PDF/A (archival) | a-1b, a-1a, a-2b, a-2u, a-2a, a-3b, a-3u, a-3a, a-4, a-4f, a-4e |
| PDF/UA (accessibility) | ua-1 |
Standards combine as long as the combination is producible: at most one base version, at most one PDF/A standard, and at most one PDF/UA standard, all sharing overlapping PDF versions. oicana validate rejects the rest.
The defaults are standards = ["a-3b"] and tagged = true. Tagging is skipped automatically when a page range omits pages, because Typst cannot tag a partial document.
On top of comparing snapshots, oicana test exports every test document under the configured standards, so a template that cannot be produced in its declared standard fails the suite. Set pdf = false on a single test or a whole collection to skip the export.
The CLI scaffolds, validates, packages, and tests templates. See the CLI documentation for installation and the full reference.
oicana new invoice # scaffold a template
oicana validate -a # check every manifest, input schema, and fallback value
oicana compile -j invoice=invoice.json # render an unpacked template
oicana watch # recompile whenever a source file changes
oicana test -a # snapshot tests, plus PDF export in the declared standards
oicana pack --all # produce the archives integrations loadIntegrations load packed archives, not directories, so oicana pack is the one command every project needs.
/ɔɪkɑna/
Oicana is source-available under the PolyForm Noncommercial License 1.0.0 and free for noncommercial use. Commercial use is free for 30 days; see pricing for subscriptions, or write to hello@oicana.com.
The Typst integration and the example projects in the Oicana GitHub organization are open source under their respective licenses. See NOTICE for a report of the third party licenses in this project.