Typst Guide

Typst Template Creation

Define a template function. Apply with #show: template.with(...). Publish to @preview for community use.

A minimal academic paper template

// lib.typ — your template definition
#let academic-paper(
  title: "Title",
  authors: (),                       // array of (name, affiliation, email)
  abstract: [],
  body,
) = {
  // Document defaults
  set page(paper: "us-letter", margin: 1in)
  set text(font: "Times New Roman", size: 11pt)
  set par(justify: true, leading: 1em)
  set heading(numbering: "1.")

  // Title block
  align(center)[
    #text(size: 18pt, weight: "bold")[#title]

    #v(1em)

    #grid(
      columns: (1fr,) * authors.len(),
      ..authors.map(a => align(center)[
        #text(weight: "bold")[#a.name] \
        #text(size: 9pt)[#a.affiliation \ #a.email]
      ])
    )
  ]

  v(2em)

  // Abstract
  if abstract != [] {
    align(center)[
      #text(weight: "bold")[Abstract]
    ]
    v(0.5em)
    pad(left: 1em, right: 1em, abstract)
    v(2em)
  }

  // Body
  body
}

How users apply the template

// main.typ
#import "@preview/academic-paper:0.1.0": academic-paper

#show: academic-paper.with(
  title: "Your Paper Title",
  authors: (
    (name: "First Author", affiliation: "University Name", email: "first@author.com"),
    (name: "Second Author", affiliation: "Other Institution", email: "second@other.com"),
  ),
  abstract: [
    Your abstract goes here.
    Multiple sentences. The template handles formatting.
  ],
)

= Introduction

Body content starts here. The template handled the title, authors, and abstract.

= Methods

= Results

#bibliography("references.bib", style: "ieee")

Template package structure

academic-paper/
├── typst.toml                 # manifest
├── lib.typ                    # template function
├── README.md                  # documentation + screenshots
├── LICENSE
├── template/                  # starter files for "typst init"
│   ├── main.typ
│   ├── references.bib
│   └── figures/.gitkeep
└── examples/
    └── basic.typ              # working example

Publishing as a template (vs regular package)

Add a [template] section to typst.toml so users can use typst init:

[package]
name = "academic-paper"
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["Your Name"]
license = "MIT"
description = "A clean academic paper template"

[template]
path = "template"           # starter files directory
entrypoint = "main.typ"     # which file is the entry point
thumbnail = "thumbnail.png" # optional preview image

Then users run typst init @preview/academic-paper to get a starter project.

Common patterns

  • Use the .with() pattern. Don't expect users to call the template function directly with positional arguments. .with() is more readable.
  • Provide sensible defaults. Title defaults to "Title", abstract empty, etc. Users only override what they need.
  • Compose with show rules. Apply #show heading: ... inside the template to customize headings without affecting user's overrides.
  • Document the API. README should list all parameters, types, defaults, and have at least one screenshot of output.
Browse Typst templates

TypeTeX includes pre-built academic templates and supports importing community templates from @preview. Browse what's available at typst.app/universe.

Try TypeTeX free

Frequently Asked Questions

What's a Typst template?

A Typst template is a function that wraps a document with predefined styles, layout, and structure. Users call it with #show: my-template.with(...) to apply the template to their document. Common templates: NeurIPS paper, IEEE conference, modern CV, thesis.

How do I create a template?

Define a function that takes named arguments and returns a styled document body. Use #show rules and #set rules inside the template function. Export the template function. Users apply it with #show: template.with(title: "...", author: "...").

What's the .with() pattern?

Typst's syntax for partial application: #show: my-template.with(title: "Title", author: "Author") creates a configured version of the template, then applies it to the document body. This is how academic templates expose configuration to users.

How do I publish a template?

Same as any Typst package — typst.toml + lib.typ. For templates, also include a template/ directory with starter files. Users run 'typst init @preview/PACKAGE' which copies the starter files into a new project. Submit to github.com/typst/packages PR for @preview namespace.

What goes in the template/ directory?

Starter files users get when they init: main.typ (entry point with #show: ...), references.bib (empty BibTeX), figures/ folder (placeholder image). Make it minimal — just enough that 'typst init' produces a compilable project the user can fill in.

How do I structure the template function?

Function takes named args (title, author, abstract, body), then constructs a styled document. Body comes from the user's content via #show: template.with(...) [body content]. Inside the template, apply #set/#show rules and lay out the title/author/abstract before yielding the body.

How do I let users override styles?

Don't enforce overrides — let user-side #set rules take precedence over your template's defaults. Only #show rules in the template function are local; #set rules cascade. So if a user does #set text(size: 13pt) AFTER your #show: template.with(...), the text size is 13pt.

What's a good example template to study?

The @preview/charged-ieee template (a popular IEEE-style template) is well-structured. Its lib.typ shows the .with() pattern, named arguments for title/author/abstract, and how to compose layout rules. Read its source for a worked example.

More Typst guides