Doc-to-PDF Skill (Typst)
Prepare documents into professional PDFs using Typst - a modern typesetting system with native math, bibliography, cross-references, and fast compilation.
Prerequisites
bash
# Check installation typst --version typstyle --version
Installation
macOS:
bash
brew install typst cargo install typstyle
Linux:
bash
# Via cargo cargo install typst-cli typstyle # Or download from GitHub releases # https://github.com/typst/typst/releases
Editor Setup:
- •VS Code: Install
tinymistextension (LSP + preview) - •Neovim: Use
typst-lsportinymist
Quick Start
bash
# Create from template typst init @preview/charged-ieee # Compile typst compile main.typ # Watch mode (live rebuild) typst watch main.typ # Output to specific path typst compile main.typ build/output.pdf
Project Structure
code
project/ ├── main.typ # Main document ├── refs.bib # Bibliography (BibTeX or YAML) ├── template.typ # Custom template (optional) ├── fig/ # Figures └── build/ # Output
Basic Document
typst
#set document(title: "My Document", author: "Author Name")
#set page(paper: "us-letter", margin: 1in)
#set text(font: "New Computer Modern", size: 11pt)
#set heading(numbering: "1.1")
#set math.equation(numbering: "(1)")
= Introduction
This is a paragraph with inline math $E = m c^2$.
Display math:
$ integral_0^infinity e^(-x^2) dif x = sqrt(pi) / 2 $
== Subsection
See @fig:example and @eq:quadratic.
$ x = frac(-b plus.minus sqrt(b^2 - 4 a c), 2 a) $ <eq:quadratic>
#figure(
image("fig/diagram.png", width: 80%),
caption: [A diagram showing the process.]
) <fig:example>
#bibliography("refs.bib", style: "ieee")
Math Syntax
Typst math is cleaner than LaTeX - no backslashes needed for common symbols:
| Typst | LaTeX | Result |
|---|---|---|
alpha, beta, gamma | \alpha, \beta, \gamma | Greek letters |
x^2, x_n | x^2, x_n | Super/subscript |
frac(a, b) | \frac{a}{b} | Fractions |
sqrt(x) | \sqrt{x} | Square root |
sum_(i=0)^n | \sum_{i=0}^{n} | Summation |
integral_a^b | \int_a^b | Integral |
arrow.r, arrow.l | \rightarrow, \leftarrow | Arrows |
plus.minus | \pm | Plus-minus |
dots.h, dots.v | \cdots, \vdots | Dots |
Math Environments
typst
// Aligned equations $ a &= b + c \ &= d + e $ // Cases $ f(x) = cases( 0 &"if" x < 0, 1 &"if" x >= 0 ) $ // Matrices $ mat(1, 2; 3, 4) $ // Delimiters $ lr(angle.l x, y angle.r) $
Theorems
typst
#import "@preview/ctheorems:1.1.3": *
#show: thmrules
#let theorem = thmbox("theorem", "Theorem", fill: rgb("#e8f4e8"))
#let lemma = thmbox("lemma", "Lemma", fill: rgb("#e8f0f8"))
#let proof = thmproof("proof", "Proof")
#theorem("Pythagorean")[
For a right triangle: $a^2 + b^2 = c^2$
]
#proof[
By construction...
]
Bibliography
BibTeX Format (refs.bib)
bibtex
@article{einstein1905,
author = {Einstein, Albert},
title = {On the Electrodynamics of Moving Bodies},
journal = {Annalen der Physik},
year = {1905},
volume = {17},
pages = {891--921},
doi = {10.1002/andp.19053221004}
}
Hayagriva YAML Format (refs.yaml)
yaml
einstein1905:
type: Article
title: On the Electrodynamics of Moving Bodies
author: Einstein, Albert
date: 1905
parent:
type: Periodical
title: Annalen der Physik
volume: 17
page-range: 891-921
serial-number:
doi: "10.1002/andp.19053221004"
Citation Styles
typst
// IEEE numeric
#bibliography("refs.bib", style: "ieee")
// APA
#bibliography("refs.bib", style: "apa")
// Chicago
#bibliography("refs.bib", style: "chicago-author-date")
// Custom CSL
#bibliography("refs.bib", style: "custom.csl")
Citations in Text
typst
As shown by @einstein1905... Multiple sources @ref1 @ref2 @ref3.
Cross-References
typst
// Define labels = Introduction <sec:intro> $ E = m c^2 $ <eq:energy> #figure(...) <fig:diagram> #figure(table(...)) <tab:results> // Reference them See @sec:intro for details. From @eq:energy we derive... As shown in @fig:diagram and @tab:results.
Figures & Tables
Figures
typst
#figure(
image("fig/plot.svg", width: 100%),
caption: [Experimental results.],
) <fig:results>
// Side-by-side figures
#grid(
columns: 2,
gutter: 1em,
figure(image("a.png"), caption: [First]),
figure(image("b.png"), caption: [Second]),
)
Tables
typst
#figure(
table(
columns: 3,
align: (left, center, right),
stroke: none,
table.hline(),
table.header[*Method*][*Accuracy*][*Time*],
table.hline(),
[Baseline], [85.2%], [1.2s],
[Ours], [*92.1%*], [0.8s],
table.hline(),
),
caption: [Comparison of methods.],
) <tab:comparison>
Academic Templates
IEEE (charged-ieee)
bash
typst init @preview/charged-ieee
typst
#import "@preview/charged-ieee:0.1.4": ieee
#show: ieee.with(
title: [Your Paper Title],
authors: (
(
name: "Author Name",
department: [Department],
organization: [University],
location: [City, Country],
email: "author@example.com"
),
),
abstract: [Your abstract here...],
index-terms: ([Term 1], [Term 2]),
bibliography: bibliography("refs.bib"),
)
= Introduction
...
LNCS / Springer (fine-lncs)
bash
typst init @preview/fine-lncs
typst
#import "@preview/fine-lncs:0.2.0": lncs, institute, author
#let inst = institute("University Name", addr: "City, Country")
#show: lncs.with(
title: "Paper Title",
authors: (
author("Author Name", insts: (inst,), orcid: "0000-0000-0000-0000"),
),
abstract: [Abstract text...],
keywords: ("keyword1", "keyword2"),
bibliography: bibliography("refs.bib"),
)
ACM (clean-acmart)
bash
typst init @preview/clean-acmart
typst
#import "@preview/clean-acmart:0.0.1": acmart
#show: acmart.with(
title: [Paper Title],
authors: (
(name: "Author", email: "a@b.com", affiliation: "University"),
),
conference: (
name: [ACM Conference],
short: [CONF '25],
year: [2025],
date: [Month Day],
venue: [City, Country],
),
)
NeurIPS (bloated-neurips)
bash
typst init @preview/bloated-neurips
typst
#import "@preview/bloated-neurips:0.7.0": neurips2025
#show: neurips2025.with(
title: [Paper Title],
authors: (authors, affiliations),
abstract: [Abstract...],
bibliography: bibliography("refs.bib"),
accepted: false, // true for camera-ready, none for preprint
)
arXiv (arkheion)
bash
typst init @preview/arkheion
typst
#import "@preview/arkheion:0.1.1": arkheion
#show: arkheion.with(
title: "Paper Title",
authors: (
(name: "Author", email: "a@b.com", affiliation: "Org", orcid: "..."),
),
abstract: [Abstract...],
keywords: ("kw1", "kw2"),
date: "December 2025",
)
Linting & Formatting
typstyle (Formatter)
bash
# Install cargo install typstyle # Format in place typstyle -i main.typ # Check formatting (CI) typstyle --check main.typ # Format all files typstyle -i **/*.typ
Configuration (.typstyle.toml)
toml
# Column width for line wrapping column_width = 80
Useful Packages
typst
// Diagrams
#import "@preview/fletcher:0.5.0": diagram, node, edge
// Code highlighting
#import "@preview/codly:1.0.0": *
// Units
#import "@preview/unify:0.6.0": num, qty
$qty("9.81", "m/s^2")$
// Glossary
#import "@preview/glossarium:0.5.0": *
// Algorithms
#import "@preview/algorithmic:1.0.0": algorithm
Makefile
makefile
MAIN = main.typ OUT = build PDF = $(OUT)/main.pdf .PHONY: all watch clean lint fmt all: $(PDF) $(PDF): $(MAIN) refs.bib @mkdir -p $(OUT) typst compile $(MAIN) $(PDF) watch: typst watch $(MAIN) $(PDF) lint: typstyle --check $(MAIN) fmt: typstyle -i $(MAIN) clean: rm -rf $(OUT)
CI/CD (GitHub Actions)
yaml
name: Build PDF
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Typst
uses: typst-community/setup-typst@v4
- name: Check formatting
run: |
cargo install typstyle
typstyle --check main.typ
- name: Build PDF
run: typst compile main.typ output.pdf
- name: Upload PDF
uses: actions/upload-artifact@v4
with:
name: paper
path: output.pdf
Quick Reference
bash
# New project from template typst init @preview/charged-ieee # Compile typst compile main.typ # Watch mode typst watch main.typ # Format typstyle -i main.typ # Check formatting typstyle --check main.typ
Troubleshooting
| Issue | Solution |
|---|---|
| Package not found | Run typst update or check package name |
| Font missing | Install font or use #set text(font: "...") |
| Bibliography empty | Check .bib syntax, ensure @key matches |
| Figure not found | Use path relative to main.typ |
| Slow compilation | Split into modules with #include |