Touying (投影 in Chinese, /tóuyǐng/, meaning projection) is a user-friendly, powerful, and efficient package for creating presentation slides in Typst.
If you like it, consider giving a star ⭐ on GitHub. Touying is a community-driven project — feel free to suggest ideas and contribute!
- Beautiful themes — built-in themes like Simple, Metropolis, Dewdrop, University, Aqua, Stargazer and diverse themes on Typst Universe
- Fast — Typst compiles in milliseconds. Live previews update as you type, giving you the instant feedback.
- Rich animations —
#pause,#meanwhile, math equation animations, CeTZ & Fletcher support - Heading-based slides — write presentations like a document, no boilerplate
- Speaker notes — dual-screen support via tools like PowerPoint, HTML or pympress
- Export — Builtin PDF export, PPTX and HTML via touying-exporter
- Correct bookmarks — proper PDF outline and page numbers out of the box
- End-to-end ecosystem — generate and check complete decks with the SeaSlides Skill, then edit them WYSIWYG and present in Tylina
- Full documentation and references (English & Chinese)
- Ask DeepWiki or Ask Zread for AI-assisted help
- Gallery — slides made by the community
- Universe — Diverse touying themes on Typst Universe
- SeaSlides Skill — AI-native deck generation, quality checks, and PDF/PNG/PPTX export
- Tylina — local-first WYSIWYG Typst editing, templates, agents, and presenting
- Share slides instantly on GitHub with gistd or export slides to PPTX and HTML formats and show presentation online.
Choose the workflow that fits how you want to work with Touying:
- Use Tylina for a local-first WYSIWYG desktop editor with templates, AI agents, slide management, and presenting built in.
- Use the Typst Web App to edit and compile in the browser.
- Install Typst locally and use Tinymist LSP in an editor with LSP support, including the VS Code extension, for a source-focused development workflow.
Then create a .typ file with the following content:
#import "@preview/touying:0.7.4": *
#import themes.simple: *
#show: simple-theme.with(aspect-ratio: "16-9")
= Title
== First Slide
Hello, Touying!
#pause
Hello, Typst!Congratulations on creating your first Touying slide! 🎉
Touying supports incremental reveal with #pause and #meanwhile, math equation animations, and integrations with CeTZ and Fletcher:
| Math equations | CeTZ & Fletcher |
|---|---|
![]() |
![]() |
For the full feature set — cover mode, callback-style animations, #uncover, #only, #alternatives — see the documentation.
For a comprehensive example showcasing university theme, theorems, CeTZ/Fletcher animations, speaker notes, and more. You can also use the #slide[..] format to access more powerful features provided by Touying.
#import "@preview/touying:0.7.4": *
#import themes.university: *
#import "@preview/cetz:0.5.2"
#import "@preview/fletcher:0.5.8" as fletcher: node, edge
#import "@preview/numbly:0.1.0": numbly
#import "@preview/theorion:0.6.0": *
#import cosmos.clouds: *
#show: show-theorion
// cetz and fletcher bindings for touying
#let cetz-canvas = touying-reducer.with(reduce: cetz.canvas, cover: cetz.draw.hide.with(bounds: true))
#let fletcher-diagram = touying-reducer.with(reduce: fletcher.diagram, cover: fletcher.hide)
#show: university-theme.with(
aspect-ratio: "16-9",
// align: horizon,
// config-common(handout: true),
config-common(frozen-counters: (theorem-counter,)), // freeze theorem counter for animation
config-info(
title: [Title],
subtitle: [Subtitle],
author: [Authors],
date: datetime.today(),
institution: [Institution],
logo: emoji.school,
),
)
#set heading(numbering: numbly("{1}.", default: "1.1"))
#title-slide()
== Outline <touying:hidden>
#components.adaptive-columns(outline(title: none, indent: 1em))
= Animation
== Simple Animation
We can use `#pause` to #pause display something later.
#pause
Just like this.
#meanwhile
Meanwhile, #pause we can also use `#meanwhile` to #pause display other content synchronously.
#speaker-note[
+ This is a speaker note.
+ You won't see it unless you use `config-common(show-notes-on-second-screen: right)`
]
== Complex Animation
At subslide #touying-fn-wrapper((self: none) => str(self.subslide)), we can
use #uncover("2-")[`#uncover` function] for reserving space,
use #only("2-")[`#only` function] for not reserving space,
#alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives.
== Callback Style Animation
#slide(
repeat: 3,
self => [
#let (uncover, only, alternatives) = utils.methods(self)
At subslide #self.subslide, we can
use #uncover("2-")[`#uncover` function] for reserving space,
use #only("2-")[`#only` function] for not reserving space,
#alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives.
],
)
== Math Equation Animation
Equation with `pause`:
$
f(x) &= pause x^2 + 2x + 1 \
&= pause (x + 1)^2 \
$
#meanwhile
Here, #pause we have the expression of $f(x)$.
#pause
By factorizing, we can obtain this result.
== CeTZ Animation
CeTZ Animation in Touying:
#cetz-canvas({
import cetz.draw: *
rect((0, 0), (5, 5))
(pause,)
rect((0, 0), (1, 1))
rect((1, 1), (2, 2))
rect((2, 2), (3, 3))
(pause,)
line((0, 0), (2.5, 2.5), name: "line")
})
== Fletcher Animation
Fletcher Animation in Touying:
#fletcher-diagram(
node-stroke: .1em,
node-fill: gradient.radial(blue.lighten(80%), blue, center: (30%, 20%), radius: 80%),
spacing: 4em,
edge((-1, 0), "r", "-|>", `open(path)`, label-pos: 0, label-side: center),
node((0, 0), `reading`, radius: 2em),
edge((0, 0), (0, 0), `read()`, "--|>", bend: 130deg),
pause,
edge(`read()`, "-|>"),
node((1, 0), `eof`, radius: 2em),
pause,
edge(`close()`, "-|>"),
node((2, 0), `closed`, radius: 2em, extrude: (-2.5, 0)),
edge((0, 0), (2, 0), `close()`, "-|>", bend: -40deg),
)
= Theorems
== Prime numbers
#definition[
A natural number is called a #highlight[_prime number_] if it is greater
than 1 and cannot be written as the product of two smaller natural numbers.
]
#example[
The numbers $2$, $3$, and $17$ are prime.
@cor_largest_prime shows that this list is not exhaustive!
]
#theorem(title: "Euclid")[
There are infinitely many primes.
]
#pagebreak(weak: true)
#proof[
Suppose to the contrary that $p_1, p_2, dots, p_n$ is a finite enumeration
of all primes. Set $P = p_1 p_2 dots p_n$. Since $P + 1$ is not in our list,
it cannot be prime. Thus, some prime factor $p_j$ divides $P + 1$. Since
$p_j$ also divides $P$, it must divide the difference $(P + 1) - P = 1$, a
contradiction.
]
#corollary[
There is no largest prime number.
] <cor_largest_prime>
#corollary[
There are infinitely many composite numbers.
]
#theorem[
There are arbitrarily long stretches of composite numbers.
]
#proof[
For any $n > 2$, consider $
n! + 2, quad n! + 3, quad ..., quad n! + n
$
]
= Others
== Multiple columns
#cols[
First column.
][
Second column.
]
== Multiple columns with equal height blocks
#cols(columns: (1fr, 1fr), gutter: 1em, lazy-layout: true)[
#emph-block[
First column with equal height: #lorem(10)
#lazy-v(1fr)
]
][
#emph-block[
Second column with equal height: : #lorem(15)
#lazy-v(1fr)
]
]
== Multiple Pages
#lorem(200)
#show: appendix
= Appendix
== Appendix
Please pay attention to the current slide number.Touying provides the presentation engine and keeps the result in readable, portable Typst source. These companion projects add higher-level generation and editing workflows without replacing that source-first foundation.
SeaSlides Skill is an AI-native presentation-generation skill and toolchain built around Touying. Give it a topic, document, URL, or Markdown file and it can plan the narrative, select or create a theme, author editable Typst/Touying source, add speaker notes, compile the deck, run quality checks, and export PDF, PNG, or PPTX. Quick Mode produces a fast first draft; Full Mode adds research, asset generation, a separate design specification, and deeper visual review.
Tylina is a local-first, document-first, AI-native WYSIWYG Typst
desktop editor. The typeset page is the editor—not merely a preview: click, select, and type on the
rendered document, then open Source Lens or Split when source-level control is needed. Tylina can
connect your own ACP agent, run the SeaSlides Skill in the current project, browse Tylina Slides and
Typst Universe templates, manage slide thumbnails and speaker notes, reorder pages, and present the
deck. The standard .typ source remains canonical throughout.
Download Tylina · Watch the editing demo

Generate with the SeaSlides Skill, then inspect, edit, reorder, and present in Tylina.

Start from a curated presentation design or browse the wider Typst Universe without leaving the desktop workflow.
Thanks to...
- @andreasKroepelin for the
polyluxpackage - @zral0kh for the waypoint feature and many improvements
- @enklht for many fixes and improvements
- @Enivex for the
metropolistheme - @drupol for the
universitytheme - @pride7 for the
aquatheme - @Coekjan and @QuadnucYard for the
stargazertheme - @ntjess for contributing to
fit-to-height,fit-to-widthandcover-with-rect





