記事一覧ページへ移動

Typstによるスライド作成のすすめ

2026-08-02
2026-08-02

わたすけです。皆さん、スライド作ってますか?僕は作っています。Typstで。

2026年3月、つくばで行われた Kernel/VM探検隊@つくば No3 において初めてTypstによるスライドづくりを試みたのを皮切りに、現在に至るまで全てのスライドをTypstで作っています。高専時代はずっとGoogleスライドを使って作っていたのですが、今となってはやはりTypstのほうが便利だなあという気持ちです。

この前Twitterで「Typstを使ってスライドを作ると良いとされている」とツイートしたところ、FF外からの反応がちらほら見られて、流れが来ているなあという気持ちになっています。さらに、最近、特に研究室において「Typstでスライド作るのって良いですよ~」と布教する機会が増えてきました。Typst によるスライドづくりを始めてまだ4ヶ月くらいしか経っていませんが、ここで僕の主張をまとめておいて、布教を楽にしようと思います。

ちなみに、僕が今まで作成したスライドは、ソースコードも含めて以下のリポジトリから閲覧できます:

GitHub - watasuke102/slides: My presentation assets made by TypstGitHub - watasuke102/slides: My presentation assets made by Typsthttps://github.com/watasuke102/slidesMy presentation assets made by Typst. Contribute to watasuke102/slides development by creating an account on GitHub.

なんと、Typst 100%です(それはそう)。

DISCLAIMER

Typstを使ってスライドを作る利点を挙げるにあたり、既存のGoogleスライドとかMarpとかそのあたりの欠点について言及することがありますが、これらのツールが、ましてやその利用者が劣っている、という事を言いたいわけではありません。あと、僕は今までずっとGoogleスライドを使っており、それ以外の、例えばMarpとかPowerPointあたりについては詳しくありません。Typstの利点って言ってるけどそれMarpでも出来るが?と思う人もいるかもしれませんが、ご了承ください。基本的には慣れていたり気に入っていたりする手法で作れば良いのですが、もしかしたらTypstでもっと良い体験を得られるかもしれないよ、と主張したいという意図でこの記事を書いています。

そもそもTypstが便利である

高専低学年のころ、LaTeXを使い始めたときの感動は今でも覚えています。プログラミングの授業においてレポート課題が課されて、コードをコピペしなくてもシンタックスハイライト付きの文書を作れることのうれしさといったら!プログラムを編集してもコピペをやり直す必要がないし、.texファイルも簡潔になってうれしいです。

それ以前は、VSCodeでコピーしてからWordにペーストするとシンタックスハイライトが付くのでそれを使っていました。白背景であるWordに合わせるためにわざわざライトテーマに切り替えてからコピペしてましたね。あとVSCodeVimを使っているときにVimのヤンクを使うとシンタックスハイライトが付かないので、ビジュアルモードで選択してからわざわざ右クリック→コピーを選択していました(Ctrl+CはVimに吸われるので使えない)。

Typstを使い始めたのは高専5年になってからです。Typstだとソースコードは#raw(block: true, read("path/to/code.cpp"))で挿入できます。便利すぎる!!!

とりあえずTypstの何が良いのかを列挙したいと思います。なお、僕はLaTeXに成熟しているというわけではなく、基本的な使い方のみ知っているという程度なので、ポジショントークである面は十分にあるとは思っています。

全てが簡潔

まず記述が簡潔です。LaTeXだとプリアンブルを長々と書かなければいけないという印象がありますよね。ドキュメントのメイン部分は必ず \(begin|end){document} で囲まなければいけないはずです。

Typstは何も書いていない状態から何かを書くだけで、それが即座に表示されます。

あと、型の概念があって、関数(マクロ)が書きやすいです1。実際に表示されるものを表す content 型は若干独特ですが、よく見られる配列や辞書型なんかもあったりします。配列にmapやreduceがあって、めちゃくちゃうれしい!!

強力なエコシステム

Typstを使い始めたいと思ったら、まずVSCodeに「Tinymist Typst」を入れる必要があります。なんと、これでおしまいです。よくわからない大量のパッケージをシステムに入れる必要もありません。VSCodeでTypstファイル(拡張子.typ)を開くと、Tinymistでリアルタイムプレビューが出来ます。一度触ってみてほしいのですが、本当に信じられないほどプレビューの反映速度が速くてすごいです。「リアルタイム」プレビューという点に一切の誇張がないことが分かると思います。設定によっては、ファイルを保存した瞬間にPDFを生成することも出来ます。もちろん爆速です。

VSCodeを使っていないならWebアプリもあります。僕は使ったことないです。VSCodeで本当に完結するので。あるいは、システムにTypstのコンパイラをインストールして、typst watchコマンドを使えば、ファイルを編集した直後にこれまた爆速でPDF等を生成してくれます。コンパイラのインストールは、Rustツールチェインが使える環境なら cargo install --locked typst-cli を打つだけです。Windowsなら winget install --id Typst.Typst で、Brewが使えるmacOS環境なら brew install typst でインストール出来ます。当然Linuxも様々なディストリビューションにインストールできます。Arch Linux や NixOS はもちろん、Snapが有効な環境ならそれを経由してインストールすることもできるらしいです。まあおすすめはやっぱりVSCodeですけどね。僕は最近エディタとしてNeovimばっかり使っているのですが、Typstだけは例外的にVSCodeを使っています。

Typstの標準機能に不満がある場合、パッケージを追加することも出来ます。パッケージリポジトリことTypst Universeから好みのパッケージを探して、Typstファイルに #import "@preview/cetz:0.5.2": * みたいな文2を書けば、すぐにパッケージを使えます。明示的なインストール作業は必要ありません。かなりうれしいです。

公式ドキュメントが整備されている

typst.app/docs に行くとドキュメントを読むことが出来ます。検索欄もあってうれしい!

まあLaTeXは長い歴史と人口の多さだけあって情報はネットに散乱していますけどね。だいたいOverleafのドキュメントを見がちな気もします。検索すれば出てくるという点で、正直LaTeXにもそこまで不満はないのですが、「基本的にWeb検索をせずとも公式ドキュメントに行けばほぼ解決する」という信頼感があるのはやはりうれしいです。


……というわけなので、僕は学校で求められるレポート作成はもちろん、授業ノートにさえTypstを使っています。レポートでよく使う様式をテンプレートとして定義して使いまわしています。こういうふうに、個人用パッケージをさっくり作成できるのもうれしいポイントですね。

Typstによるスライド作成のすすめ

タイトル回収!

ちょうど良い表現力

テキストベースでスライドを作る方法といえば Marp や Slidev を思い浮かべる人が多いと思います。僕も昔Slidevに挑戦しようとしてやめた過去があります。

何が嫌だったのかというと、Markdownにおける表現力の低さです。Markdownは本当にシンプルなマークアップ記法のみを備えています。もちろんそれがMarkdownの良いところなのですが、スライドを作る際にこの表現力の低さは仇となります。つまり、スライドを作るうえで当然に出てくる、「この部分はちょっとフォントサイズを小さくしたい」とか、「ここだけ色を変えたい」とか、「図形を挿入したい」といった需要は、当たり前ですが一般的なMarkdownでは不可能です。

Marpは知らないですが、Slidevはそれを補うためにVueによるコンポーネント定義をサポートしていたと記憶しています。ただ、個人的な印象なのですが、CSSはスライドづくりに適していないのでは、と思っています。CSSは、確かに表現力はかなり高いのですが、ちょっとしたことをやるためには記述量が多すぎるのでは?という気持ちがあります。マジで知らないんですけど、UnoCSSのおかげで緩和されてたりするんですかね。あと、表現力が高いとして、そのレベルの表現力がスライドに求められることがあるのか?みたいな気持ちもあります。

例えばグリッドレイアウトを作るとき、<div style="display: grid; grid-template-columns: repeat(3, auto);"> ... </div> みたいなことを書くわけじゃないですか。Typstだとこれに相当する記述は #grid(columns: 3, ...) です。例が例なので良くないかもしれませんが……。

あと、Typstならではの機能が使えるのも強力です。例えば、以下は僕が最近作ったスライドからの抜粋ですが、こういう目次スライドを作りたいと思うことは多いのではないでしょうか。僕は多いです。

僕は自分のTypstテンプレート#template_section() という関数を定義しています。こういう定義となっていますが、メイン部分はこんな感じです (ちょっと改変しています) 3

#let template_section(name) = {
  if name != "" {
    place(hide([= #name <section_header>]))
  }

  table(
    query(<section_header>)
      .enumerate()
      .map(e => {
        // 1-indexed に変換
        let i = e.at(0) + 1
        // この時点でカウンタはインクリメントされているため、1つ減らす
        let current = section_counter.get().at(0) - 1
        let appearance = it => it
        if current > 0 {
          if i < current {
            // すでに発表したセクション
            appearance = text.with(fill: gray2)
          } else if i == current {
            // 今から始まるセクション
            appearance = text.with(fill: green, weight: "bold")
          }
        }
        (
          appearance(table.cell[#i.]),
          appearance(table.cell(e.at(1).body)),
        )
      })
      .flatten()
  )
}

まず、引数が空文字列ではないなら、不可視の見出しとして引数をレンダリングしておきます。このとき、<section_header>ラベルを見出しに付与しておきます。そうしたら、#query() を用いて、そのラベルが付いている見出しを列挙して、この関数が呼ばれた回数にもとづいて各セクションの表示を変えつつ列挙する、という感じです。

これのおかげで、前述したような目次は #template_section("何をしている人?") と呼び出すだけで勝手に更新されます。呼び出しを消すと、もちろん目次から消えます。セクション構成を更新するたびに散らばっている目次ページすべてを変更する必要はありません。本当にうれしい!

あと、最近、僕は研究内容について発表するスライドをTypstで作りました。目次としては、背景・関連研究・提案手法とかそういう感じのものがあります。あと、内容が複数ページにわたる場合、「背景 (2/5)」のように、そのセクションの総ページ数と現在地を表示すべき、と言われていました4

Typstだと、これを以下のような関数として定義できます:

// キーと見出しの対応関係を辞書として定義
#let heading_map = (
  "bg": "背景",
  "related-work": "関連研究",
  "method": "提案手法",
  "plan": "今後の予定",
)
#let page_heading(key) = {
  // カウンターをインクリメント
  counter(key).step()
  stack(
    dir: ltr,
    spacing: 0.4em,
    // キーに対応する文字列を見出しとして表示
    [== #heading_map.at(key)],
    align(horizon, text(
      fill: gray1,
      // 2ページ以上ある場合は番号を表示
      context if counter(key).final().at(0) > 1 {
        // カウンターの値を `(現在の値 / 最終的な値)` として表示
        counter(key).display(
          "(1 / 1)",
          both: true,
        )
      // 1ページだけだった場合は何も表示しない
      } else [],
    )),
  )
}

あとは見出しを表示したいところで #page_heading("bg") と書けば見出しが表示されて、かつ勝手にカウンタがインクリメントされていきます。超うれしいです。

ここまでではなくても、やはりいろいろな機能があるというのがうれしいです。要素を単に等間隔で配置したいなら #stack() があります。グリッドを作りたいなら #grid() があります。絶対位置に表示したいなら #place() があるし、相対的にちょっとずらしたいなら #move() があります。要素を水平・垂直方向のどこかに揃えたいなら #align() があります(水平方向および垂直方向どちらも中央にしたいなら #align(center+horizon) とする)。

GUIを触らなくて良い

例えば「これらの要素は左端を揃えて、縦方向に全く同じ間隔を空けて配置したい」みたいな作業は頻発すると思います。Googleスライド等だと、要素をまず横方向にドラッグして、左の辺に合うようスナップさせて(他の要素が近くにあると、そっちにスナップしてしまって、苦しい)、次は縦方向にドラッグして、間隔が一定になっているようなインジケータが出るようにがんばる……みたいなことをしなければいけないと思います。苦しすぎませんか?

Typstだと、おそらくこれは #stack(dir: ttb, spacing: 1cm, ...) とすれば解決します。間隔を明示できて、とてもうれしい!

関数がうれしい

スライドを作っていると、同じようなレイアウトを複数箇所で使い回す、みたいなことが多いと思います。Googleスライド等でこれをやるときの苦しさは言うまでもないでしょう。Typstは関数を定義できるので、1回これを定義してしまえば、任意の場所で再利用できるし、関数定義を調整すれば呼び出し元が全て変更されます。

そもそもTypstが提供してくれる関数の豊富さは上述したとおりです。


逆にデメリットも書いておきます。

動的なコンテンツに弱い

そもそも文書作成を主とするツールなので当然といえば当然なのですが、PDFの制約により、MP4やGIFアニメーションは基本的に使えません。……が、スライド発表に限定すると5、GIFアニメーションについてはどうにかなります。後述します。

また、アニメーションも基本的に扱えません。例えばSlidevだと、shiki-magic-moveを用いてコードブロックのアニメーションが行えてかなりすごいのですが、Typstだと流石にこれは無理です。これほど複雑なものではなかったとしても、例えばオブジェクトが横からスライドしてきたり、文字が画面外からびよんびよん跳ねて登場したり、ページ全体が紙飛行機になって飛んでいったり、というゴミを煮詰めたかのようなクソアニメーションは使えません。僕はGoogleスライドでもアニメーションをほぼ使っていなかったので問題なかったという背景があります。使うとすれば箇条書きのフェードイン6くらいだったのですが、意外とフェードインなしでいいのではみたいな気持ちになっています。

編集にGUIを使えない

575

メリットの裏返しみたいなものですが、実際の文書を見ながら、要素をマウスでいじるみたいなことが出来ません。Googleスライド等だと、やはり図形の大きさおよび位置を調整するのはやりやすいですよね。他要素とのスナップもあったりしてうれしいです(まあ前述の通りおおよそどうにかなります)。

これどうにかなりませんかね。実際のプレビューとソースコードとの対応関係を持っておかないといけないのでハードルはめちゃくちゃ高そうな気がします。

実際どうやって作るの?

とりあえず作ってみたい!となったら、Typstでスライドを作るためのパッケージを使うと良いでしょう。slydstとかtypslidesとかもありますが、一番有名?なのはtouyingだと思います。Typst Universeにおいても Featured Package として紹介されているし。

これらのパッケージを使うメリットとして最も大きいものは、テーマが用意されているという点だと思います。あとtouying#pause関数を使うとクリックするまで以降のコンテンツを表示しないみたいなよくあるやつ7を簡単に実装できて良さそうです。

ただ、とりわけ自分でテーマを作りたい場合、これらのパッケージを使うメリットはそこまでないのでは、と思っています。まあ使いこなしていないだけかもしれませんが。例えばクリックしたときに次のコンテンツを表示するやつをやりたい場合、僕は以下のように書いています(以前のスライドからの抜粋):

#for i in range(4) {
  template_basic[
    == 参加するメリット:人脈
    #(
      (
        [*Twitterのフォロワーが増える*],
        [\ ……だから何?],
        [
          - 入ってくる*情報の量 / 種類が増える*
          - たのしい!
        ],
      )
        .slice(0, i)
        .join()
    )
  ]
}

謎の関数を使わなくても#forで明示的に書けばええですやんという話です。そもそも、touying#pauseはページ数表示を更新しないんですよね。そうすると、スライドに表示されるページ数とPDF上のページ数がズレます。これだと、質疑応答なんかで「スライドのxページを見せてください」と言われた時にページ数の絶対移動が出来なくて困ります。

……とはいえ、まあ見たら分かるんですが、#pauseを書くほうが明らかに簡潔でいいですよね。良し悪しかもしれません。好きな方を選んでください。パッケージを使わなくても十分スライドは作れますという主張は置いておきます。

Typstで作ったスライドをどうやって発表するか

さて、スライドを作ったら、当然それを使って発表したいですよね。最も簡単な方法としては、PDFとしてコンパイルしたのち、何らかのツールを使ってスライドを送る方法があります。少なくとも Google Chrome にはPDFをプレゼンテーションモードで表示する機能があるので、これを使うと全画面表示しつつ矢印キーでスライドを送ることができます。また、pdfpcというソフトを使っても良いでしょう。GTKベースのプレゼンテーションソフトで、スライド送りはもちろん、発表者ツールやポインターといった機能も搭載しています。僕はKernel/VMでの発表においてのみこれを使いました。

この方法の何が厳しいのかというと、PDFとしての制約が課されてしまうんですよね。つまり、GIFがアニメーションしません。多くの場合は困らないのですが、研究発表のときなんかはデモを見せたいという気持ちが発生することがあるので、どうにかしたい問題ではあります。

解決策としては、Tinymistが備えている、Typstファイルをスライドとしてプレビューする機能を使うことです。VSCodeのコマンドパレットから Typst Preview: Preview Opened file in Browser and Slide Mode とかを選ぶと良いと思います。これだとGIFがアニメーションするので、かなりうれしいです。多くの場合はこれで良さそうな気がします。

ただし、個人的には第3のアプローチを勧めたいです。すなわち、専用のスライドツールを作って使う方法です。僕はWebアプリとして以下のツールを作って発表しています。rezenterといいます。OSSなので誰でも使えますよ!

GitHub - watasuke102/rezenter: All-in-one presentation toolGitHub - watasuke102/rezenter: All-in-one presentation toolhttps://github.com/watasuke102/rezenterAll-in-one presentation tool. Contribute to watasuke102/rezenter development by creating an account on GitHub.

そもそも、なぜTinymistのプレビューだとGIFのアニメーションが動くのでしょうか?何故なら、TinymistはTypstファイルをSVGとしてビルドしたのちプレビュー表示しているからです。GIFアニメーション画像を表示するTypstファイルを作って、typst compile --format svg コマンドによって生成されたSVGをブラウザ等で表示すると、GIFアニメーションが動いているのが確認できると思います。つまり、スライドをSVGとして出力して表示できればいいわけです。

rezenter は、PDFもしくは.typファイルを読み込むことができます。Typstファイルはローカルにインストールされた typst コマンドによりSVGにコンパイルされます。Webブラウザ上でコンパイラを動かす方法ももちろんあるのですが、Typstファイルが参照する画像などの扱いや、ローカルにしかないパッケージの読み込みなどが難しくなるので、このような手法を取っています。

あとはふつうに発表するだけです。Viewer、Presenter、Controllerの3ページが用意されています。Viewerはシンプルに画面いっぱいにスライドを表示する画面です。Presenterは発表者ツールで、次のスライドをプレビューしたり、JSONで書かれた発表ノートを読んだりできます。まあ今まで発表時に発表ノート機能を使ったことはないんですけどね。

イチオシ機能はControllerです。スマートフォンから開くことを前提としたページとなっており、スマホのテザリングを有効化して、アクセスポイントにノートパソコンを繋げばすぐに開けます。Controllerページはトラックパッド的な領域を触って操作します。

こんな感じのジェスチャを備えています:

  • ダブルタップ:次のスライドに移動
  • ロングタップしてから再度タップ:前のスライド
  • 2本指でピンチ:画面の拡大縮小
  • パン(2本指を平行移動):スライドの表示位置が移動
  • 一本指でドラッグ:画面上のポインタが移動

これのおかげで、スライド送りのためにパソコンに張り付く必要がなくなって、ものすごくうれしいです。

前述の通りOSSなので、cloneしてnpm installしてnpm run buildしてからnpm startすればすぐに使い始めることが出来ます。まあ今は大LLM時代なので、自分が使いやすいようなツールを作ってみるのはかなりおすすめです。このツールも最初はGitHub Copilotに作ってもらいました。

おわりに

Typstはいいぞ&Typstによるスライド作成&発表ツール自作はいいぞ、という布教でした。Typstは基本的にシンプルな記法ながらも強力な表現力を備えており、文書づくりはもちろんスライドづくりにも便利だと思っています。ぜひ使ってみてほしいです。まずはレポートからでも十分に恩恵を受けられると思っています。

最近スライドばっかり作っていたせいか、なんか文字が多いなあという気持ちになってきました。いつかこの記事の内容をスライドにして発表したいです。

Footnotes

  1. ちなみに、これはLaTeXとの比較ではないのでご了承ください(LaTeXでまともなマクロを書いたことがないため)

  2. LaTeXにおけるTikZのようなもの。図形描画に便利な機能をたくさん提供してくれる

  3. なんと、このコード片を提示するためにShikiに乗り換えました。以前はHighlight.jsを、もっと前はPrism.jsを使っていたが、どちらもTypstに対応していない

  4. これ何の意味があるのか全く分かってないです。スライドの総ページ数を表示すべきとも言われていたのですが、これもよくわかりません。慣習??なお、現在のページ数を表示すべきというのは、質疑応答の際に「xページの内容なんですが~」という風に言及できるから、という理由があるので納得しています

  5. 配布資料としてPDF出力したスライドを公開する場合は流石にアニメーションは使えません。まあそれは他ツールで動画やアニメーションを入れた時も同じなので……

  6. デフォルトのアニメーション時間が1秒くらいあってありえなさすぎたので、アニメーション効果を適用するたびにスライダーをいじって0.2秒にしていた。何度もやると嫌になってくる作業です

  7. touyingはアニメーションと呼んでいます。一般にもアニメーションと呼ぶらしい?ですが、あんまりしっくりきていません。一定の時間をかけて(視覚上は)連続的に性質が変化するものがアニメーションなのでは?という感情をどうしても拭えないんですよね。まあ「0秒かけて移動するアニメーションですよ」と言われたら反論できないので意味のないゴネなんですが……

Comments

Powered by Giscus