Migrating to Typsite 0.1.6

In version 0.1.6, Typsite introduced a series of major updates, inevitably including some breaking-changes. This document aims to help users migrate to the new version smoothly.

1 Typsite Packages

Parts of the Typst library that are closely related to Typsite have been extracted into separate Typst packages. You can find them under typsite/packages. Typsite bundles these packages into the binary and automatically installs them to the @local @local directory during each typsite compile typsite compile .

To facilitate debugging and using packages, Typsite also supports local package auto-installation. Just specify the --packages --packages flag when running typsite compile typsite compile .

  • In watch-mode watch-mode , Typsite will also automatically update these local packages and recompile the site.

So now, the Typsite Typst libraries are split into two parts:

  • @local/typsite:0.1.0 @local/typsite:0.1.0 : Contains core functionality of Typsite, provides basic functions, and acts as an interface between Typsite and site libraries.

    • Thanks to this layer, it is unlikely for future updates to introduce more breaking-changes.
  • root/lib/ root/lib/ : The site library of each Typsite site. Users are free to customize anything here.
2 Migration

If you’re relying on site libraries from before version 0.1.6, you’ll need to make the following replacements when migrating:

  • import "lib.typ" import "lib.typ" |-> import "/lib/lib.typ" import "/lib/lib.typ"
  • html-text html-text |-> html.text html.text
  • text-align text-align |-> html.align html.align

    • (Make sure not- to replace text-align text-align inside /lib/site.typ /lib/site.typ )

It’s recommended to import lib.typ lib.typ using an absolute path. If you’re using tinymist as your LSP, you’ll need to specify the Typst root-path root-path for better experience:

  • In VSCode, you can add the following to .vscode/settings.json .vscode/settings.json in your site directory:

    "tinymist.rootPath": "absolute path of your site/root"
    "tinymist.rootPath": "absolute path of your site/root"

For any breaking-changes not anticipated here, you can easily detect them by launching watch-mode watch-mode with typsite compile --port 8000 typsite compile --port 8000 . Typsite will provide helpful error messages whenever you modify a file, allowing you to fix issues quickly.

3 Other Updates
  • Added support for converting Typst math to MathML.

    • This improves the rendering of math formulas, and the MathML conversion will detect Typst math fonts in-place for compatibility.
  • inline inline function has a new fit-font fit-font parameter, which can adapt to Typst’s context text.size context text.size .
  • For pages containing backlinks and references, duplicate tags in the <head> <head> section are now removed, resulting in a much cleaner structure.
  • In the default site library, show-rules show-rules have been modularized. You can easily add/remove/modify show-rule show-rule items in /lib/lib.typ /lib/lib.typ .
  • In the default site configuration, link titles have been optimized. You can now preview links as Link Title [Link URL] Link Title [Link URL] .

Backlinks

Typsite Documentation [index]

Typsite

1 Introduction

Typsite is a tool for building static websites. It uses pure Typst to write content and processes it through Typsite to generate a fully functional static site.

2 Features
  • Standard Typst expressions
  • Framework support: hierarchical headings, section templates, sidebar, footer
  • Rich text: paragraphs, sections, quotes, code blocks, math formulas, footnotes, page embedding
  • Typst math -> Mathml (auto detected math-font)
  • Supports modern web standards such as HTML5, CSS3, and JavaScript (ES6+)
  • Incremental compilation and real-time preview
3  Introduction to Typst [typst]

Typst is a modern typesetting system, similar to LaTeX, but designed to be more concise and easier to learn. It is primarily used to create beautifully typeset documents such as academic papers, books, and reports.

You can find the official English documentation here: Typst Document
For a Chinese tutorial on Typst, I highly recommend: The Typst Blue Book
[Oh my, the author is clearly aware that they’re explaining an ontology!].


Typst

🔥has risen!🔥




🚀Did the TeX folks miss the memo?🚀


The rest of this section will introduce Typst & HTML → Typsite

3.1 Typst’s HTML Export Feature

In version 0.13 0.13 , Typst added HTML export capabilities, including an html-export mode and two core functions: html.elem html.elem and html.frame html.frame — using these, we can write Typst documents targeting HTML+CSS output.

3.2 Typsite: A Static Site Generator Based on Typst

Inspired by this, I developed a static site generator in Rust called Typsite.

Currently, Typst’s HTML export:

  • Has good support for basic rich text
  • Requires users to manually write complex styles using the html.elem html.elem function
  • Cannot automatically convert all Typst ecosystem content into HTML
  • For content with complex Typst styles, html.frame html.frame can be used to convert them into SVG and embed them into HTML
  • Only supports single-file HTML output per compilation

For details on supported features and the roadmap, follow this issue: HTML export #5512

Although the official team plans to support automatic typst style → HTML+CSS in the future, this won’t conflict with Typsite. On the contrary, Typst’s development will make Typsite even more useful, because Typsite’s main role is to coordinate interaction between articles and ultimately build a fully functional static website.

4 Installation
  • Download the binary from the release page

    • Use the latest stable Typst (currently tested with 0.15.1)
    • Building from source requires Rust 1.89 or newer
  • Build via Nix & Flakes

    • Ensure you’ve enabled experimental-features = nix-command flakes experimental-features = nix-command flakes
git clone https://github.com/Glomzzz/typsite.git

cd typsite
nix build .
git clone https://github.com/Glomzzz/typsite.git

cd typsite
nix build .
5 Initialization

Run typsite init typsite init to initialize a Typsite project in the current directory.

.
├── root         ---  Typst root directory
│   ├── index.typ    --- Main article
│   └── lib/         --- Typsite library files; entry point: lib/lib.typ
├── .typsite     ---  Typsite configuration directory
│   ├── assets       ---  Resources (synced to output directory)
│   ├── components   ---  Component templates
│   ├── themes       ---  Code highlighting themes
│   ├── rewrite      ---  Rewrite templates
│   ├── schemas      ---  Page templates
│   └── options.toml ---  Project configuration
├── .cache       ---  Cache directory
└── publish      ---  Output directory
.
├── root         ---  Typst root directory
│   ├── index.typ    --- Main article
│   └── lib/         --- Typsite library files; entry point: lib/lib.typ
├── .typsite     ---  Typsite configuration directory
│   ├── assets       ---  Resources (synced to output directory)
│   ├── components   ---  Component templates
│   ├── themes       ---  Code highlighting themes
│   ├── rewrite      ---  Rewrite templates
│   ├── schemas      ---  Page templates
│   └── options.toml ---  Project configuration
├── .cache       ---  Cache directory
└── publish      ---  Output directory
6 Writing

Typsite is compatible with most native Typst syntax:

1For align align , please use the html.align html.align function from the library
2For complex styled elements, use the inline inline function for SVG embedding

7 CLI (Command Line Interface)
Usage: typsite <COMMAND>

Commands:
  init     Initialize a new Typsite project in the specified directory
  compile  Compile or watch a project; specify input/output [alias: c]
  clean    Clear cache and output directories
  syntect  Check the list of supported syntax and code highlighting
  help     Print this message or help info for a subcommand

Options:
  -h, --help     Print help
  -V, --version  Print version info
Usage: typsite <COMMAND>

Commands:
  init     Initialize a new Typsite project in the specified directory
  compile  Compile or watch a project; specify input/output [alias: c]
  clean    Clear cache and output directories
  syntect  Check the list of supported syntax and code highlighting
  help     Print this message or help info for a subcommand

Options:
  -h, --help     Print help
  -V, --version  Print version info
7.1 init
Initialize a new Typsite project in the specified directory

Usage: typsite init [OPTIONS]

Options:
  -d, --dir <DIR>  Project root directory [default: ./]
  -h, --help       Print help
Initialize a new Typsite project in the specified directory

Usage: typsite init [OPTIONS]

Options:
  -d, --dir <DIR>  Project root directory [default: ./]
  -h, --help       Print help
7.2 compile
Compile or watch the project with specified input and output directories

Usage: typsite compile [OPTIONS]

Options:
      --host <HOST>          Serve host [default: localhost]
      --port <PORT>          Serve port, must be specified to watch mode [default: 0]
      --config <CONFIG>      Project config [default: ./.typsite]
      --cache <CACHE>        Cache dir [default: ./.cache]
  -j, --jobs <JOBS>          Concurrent article exports [default: automatic CPU/Rayon budget]
  -i, --input <INPUT>        Typst root dir, where your typst files are stored [default: ./root] [aliases: --i]
  -o, --output <OUTPUT>      Output dir [default: ./publish] [aliases: --o]
  -p, --packages <PACKAGES>  Packages dir, will be installed to @local and will be synced to @local in watch mode, skip if empty or not found [default: ] [aliases: --p]
  -t, --typst <TYPST>        Typst executable path [default: typst]
      --no-pretty-url
      --no-short-slug
  -h, --help                 Print help
Compile or watch the project with specified input and output directories

Usage: typsite compile [OPTIONS]

Options:
      --host <HOST>          Serve host [default: localhost]
      --port <PORT>          Serve port, must be specified to watch mode [default: 0]
      --config <CONFIG>      Project config [default: ./.typsite]
      --cache <CACHE>        Cache dir [default: ./.cache]
  -j, --jobs <JOBS>          Concurrent article exports [default: automatic CPU/Rayon budget]
  -i, --input <INPUT>        Typst root dir, where your typst files are stored [default: ./root] [aliases: --i]
  -o, --output <OUTPUT>      Output dir [default: ./publish] [aliases: --o]
  -p, --packages <PACKAGES>  Packages dir, will be installed to @local and will be synced to @local in watch mode, skip if empty or not found [default: ] [aliases: --p]
  -t, --typst <TYPST>        Typst executable path [default: typst]
      --no-pretty-url
      --no-short-slug
  -h, --help                 Print help
7.3 clean
Clear cache and output directories

Usage: typsite clean [OPTIONS]

Options:
      --input <INPUT>    Protected Typst source directory [default: ./root]
      --config <CONFIG>  Protected configuration directory [default: ./.typsite]
      --force            Allow cleaning unmarked legacy directories after path checks
  -o, --output <OUTPUT>  Output directory [default: ./publish]
  -c, --cache <CACHE>    Cache directory for raw Typst HTML [default: ./.cache]
  -h, --help             Print help
Clear cache and output directories

Usage: typsite clean [OPTIONS]

Options:
      --input <INPUT>    Protected Typst source directory [default: ./root]
      --config <CONFIG>  Protected configuration directory [default: ./.typsite]
      --force            Allow cleaning unmarked legacy directories after path checks
  -o, --output <OUTPUT>  Output directory [default: ./publish]
  -c, --cache <CACHE>    Cache directory for raw Typst HTML [default: ./.cache]
  -h, --help             Print help
7.4 syntect
View the list of syntax highlighting and supported languages
Usage: typsite syntect [OPTIONS]

Options:
      --config <CONFIG>  Config path [default: ./.typsite]
  -h, --help             Print help
View the list of syntax highlighting and supported languages
Usage: typsite syntect [OPTIONS]

Options:
      --config <CONFIG>  Config path [default: ./.typsite]
  -h, --help             Print help
7.5 Build parallelism

Typsite uses Rayon to hash independent files, check export caches, parse article HTML, and render pages in parallel. Typst exports run in a separate bounded Rayon pool: the automatic limit is the available CPU budget (also respecting the Rayon pool size). Each Typst subprocess receives a share of that CPU budget through its own --jobs --jobs option, rather than letting every subprocess spawn a full machine’s worth of workers.

typsite compile --jobs 4
# Low-memory or export debugging: one article subprocess at a time.
typsite compile --jobs 1
typsite compile --jobs 4
# Low-memory or export debugging: one article subprocess at a time.
typsite compile --jobs 1

-j -j is an alias for --jobs --jobs ; the value must be positive. This setting controls simultaneous article exports, not all Rayon work. Use RAYON_NUM_THREADS RAYON_NUM_THREADS to tune Rayon hashing/parsing/rendering separately. An explicit high --jobs --jobs limit can increase memory use; it is still bounded by the number of dirty articles. No export pool is created for true no-ops.

Packages are prepared before exports start. Workers produce independent artifacts, then the build joins them and records results in stable source order. Graph resolution, dependency-ordered metadata, cache/ownership checkpoints, and stale deletions stay ordered for correctness. Independent output files publish in parallel with atomic renames and data syncing; parent directories are synced once per batch. Verified no-ops skip configuration parsing, validated highlighting resources have a content-keyed cache, and shared dependencies are checked once per export batch. Changing --jobs --jobs alone does not invalidate the cache or change site bytes.

8 RSS feed and sitemap

RSS is opt-in. The article flag rss rss defaults to false false , and the bundled base_url base_url is empty. To publish a feed, configure the site URL and select articles with #rss(true) #rss(true) on a collection page. Do not set the global article default to true.

8.1 1. Enable feed generation

Set the public site URL in .typsite/options.toml .typsite/options.toml to generate RSS 2.0 and a sitemap:

[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
sitemap_path = "/sitemap.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"
[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
sitemap_path = "/sitemap.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"

Do not add a second [site] [site] section; edit the existing one. Replace the example URL with your actual public URL, then run typsite compile typsite compile . The files are written beneath the output directory. Every generated page receives an RSS autodiscovery link in its HTML head; readers can subscribe to https://example.org/rss.xml https://example.org/rss.xml .

8.2 2. Select articles with a container

Article metadata has a boolean rss rss option, defaulting to false false . Mark a collection page with #rss(true) #rss(true) , then directly embed the articles to publish:

#import "/lib/lib.typ": *
#show: schema.with("page")
#title[My feed collection]
#rss(true)

= #embed("./first-post.typ")
= #embed("./second-post.typ")
#import "/lib/lib.typ": *
#show: schema.with("page")
#title[My feed collection]
#rss(true)

= #embed("./first-post.typ")
= #embed("./second-post.typ")

Only those directly embedded articles become feed items. The marked collection page itself is excluded, even if another collection embeds it. The marker is not inherited by embedded articles. Nested embeds are not selected as separate entries; their content still appears inside a selected article in full mode. Citations, parent metadata, and graph-only child declarations do not select items. Multiple containers contribute a union of entries, with each article appearing only once.

#rss(false) #rss(false) makes a page an ordinary article again; it can still be included if a marked container embeds it. With no marked containers (or no eligible direct embeds), the enabled feed is empty. Date ordering and rss_limit rss_limit apply after selection. The sitemap still lists all compiled articles.

Both demo homepages are marked containers. They directly embed the article guide and Typst introduction in each language, so the demo feed has four entries, not every page. For older customized libraries, import rss rss from @local/typsite:0.1.0 @local/typsite:0.1.0 or merge the new root/lib/lib.typ root/lib/lib.typ import.

8.3 3. Try it in this demo

After setting base_url base_url , run these commands from the initialized demo directory:

typsite compile
typsite compile --port 8080
typsite compile
typsite compile --port 8080

Inspect publish/rss.xml publish/rss.xml , or open http://localhost:8080/rss.xml http://localhost:8080/rss.xml while preview is running. Deploy the output and subscribe using your public URL, such as https://example.org/rss.xml https://example.org/rss.xml ; the preview address is only for local checks.

No file? Check base_url base_url , rss_path rss_path , and rss_limit rss_limit . Empty feed? Check for a marked container with eligible direct embeds. Keep [default_metadata.options].rss = false [default_metadata.options].rss = false ; #rss(true) #rss(true) belongs on the collection, not on the posts you want to publish. A self-contained upgrade walkthrough is in the 0.1.8 RSS migration instructions .

8.4 Item content and dates
  • summary summary includes a plain-text description, taking the first nonempty description description , summary summary , or abstract abstract metadata value. It does not invent an excerpt when these are absent.
  • full full additionally includes the composed article HTML in content:encoded content:encoded , including embedded articles but not the page schema, navigation, sidebar, or reference/backlink footer. Ordinary links and image URLs become absolute. Scripts are omitted; feed readers may not display SVG, MathML, interactive elements, or site-specific CSS exactly like the website.
  • Titles use page-title page-title , then title title . Articles are ordered by updated updated , lastmod lastmod , then date date , newest first, with URLs breaking ties. pubDate pubDate uses the publication date date , falling back to the modification time.
  • Dates accept YYYY-MM-DD YYYY-MM-DD , YYYY-MM-DD HH:MM[:SS] YYYY-MM-DD HH:MM[:SS] (UTC), RFC 3339, or RFC 2822. Invalid or unknown dates are omitted rather than emitting invalid RSS dates.
  • An empty base_url base_url disables both outputs. An empty rss_path rss_path or rss_limit = 0 rss_limit = 0 disables RSS only. An empty sitemap_path sitemap_path disables only the sitemap. Disabled or renamed generated files are cleaned up through the ownership journal.
  • Changing feed settings only recomposes outputs; unchanged articles are not re-exported with Typst. --no-pretty-url --no-pretty-url is reflected in article links.

Add metadata to an article with the existing helpers:

#title[An article]
#date[2026-03-02 18:25]
#metacontent("summary")[A short introduction for feed readers.]
#metacontent("updated")[2026-03-03T09:00:00Z]
#title[An article]
#date[2026-03-02 18:25]
#metacontent("summary")[A short introduction for feed readers.]
#metacontent("updated")[2026-03-03T09:00:00Z]
9 Architecture & Flow

The diagram has three lanes: read them top to bottom, each left to right. HIT reuses raw HTML; MISS invokes Typst. An unchanged published site takes the no-op exit at step 03; only dirty builds drop into the build lane for parsing, graph resolution, and whole-page composition. Tags mark parallel stages and the two independent checkpoints (A for exports, B for publication ownership), and the bottom red band explains recovery. On small screens, scroll within the diagram to read the details.

Rayon parallelizes independent hashes, article parsing, page rendering, and bounded Typst exports; package setup and publication checkpoints remain ordered. The cache stores raw Typst HTML and actual dependency hashes, not old relationships or rendered fragments. Dirty builds recompose all pages but write only changed bytes; true no-ops neither write output nor reload preview clients. Publication is atomic per file, not for the whole site; fix a reported failure and rerun to recover. See Migrating to Typsite 0.1.8 for migration and output-ownership details.

10 Configuration

You can view all default configurations here:

Based on these, you can fully customize your entire site.

  • schema: Page templates, handling page structure
  • components / rewrites: Components/Rewriters, build up the page content
  • assets: Resource files, automatically synced during compilation
  • themes: Code highlighting files
  • syntaxes: Code syntaxes files
11  Article [article]
TODO….
11.1 Metadata
11.1.1 Page Settings
11.1.2 Meta Content
11.1.3 Article Relations
11.2 Sidebar
11.3 Main Content
11.3.1 Headings
11.3.2 Paragraphs
11.3.3 Breadcrumbs
11.3.4 Embeds
11.3.5 Footnotes
11.3.6 Links
11.3.7 Formulas
11.3.8 Inline Content
11.3.9 Code
11.3.9.1 Theme
11.3.9.2 Syntax
11.3.10 Styles
11.3.10.1 Alignment
11.3.10.2 Highlight
11.3.10.3 Colored Text
11.3.10.4 Bold
11.3.10.5 Italic
11.4 Footer
11.4.1 Backlinks
11.4.2 References
Why not take a look at Content Example first?

Migrating to Typsite 0.1.7 [migrate-to-017]

In version 0.1.7, Typsite introduced a series of major updates about SVG-compat, inevitably including some breaking-changes. This document aims to help users migrate to the new version smoothly.

1 0.1.6 Migration

Make sure you’ve done: Migrating to Typsite 0.1.6

2 .typsite Configuration Migration

In version 0.1.7, the following new components and rewrites were added to the .typsite directory:

  • .typsite/components/anchor_def_svg.html .typsite/components/anchor_def_svg.html : SVG anchor definition component
  • .typsite/components/anchor_goto_svg.html .typsite/components/anchor_goto_svg.html : SVG anchor goto component
  • .typsite/rewrite/footnote-ref-svg.html .typsite/rewrite/footnote-ref-svg.html : Footnote reference rewrite for SVG

If you’re upgrading from an older version, make sure to copy these new files to your site’s .typsite directory.

3 /root/lib Library Migration
3.1 inline Function Signature Change

The fit-font fit-font parameter semantics of the inline inline function have changed:

  • Before 0.1.7: fit-font fit-font was a bool bool type
  • After 0.1.7: fit-font fit-font is a 1em 1em type (can be true true , false false , or values like 1em 1em , 2em 2em )

Migration:

  • inline(content, fit-font: true) inline(content, fit-font: true) |-> inline(content, fit-font: 1em) inline(content, fit-font: 1em)
  • inline(content, fit-font: false) inline(content, fit-font: false) |-> inline(content) inline(content) or inline(content, fit-font: false) inline(content, fit-font: false)
3.2 Library Import Changes

If you’ve customized the inline inline function in your site library, you need to update the call signature:

// Old version
#import "@local/typsite:0.1.0": inline

// New version
#let footnotes = state("footnotes", ())
#let inline(..args) = context {
  import "@local/typsite:0.1.0": inline
  inline(..args, footnotes: footnotes.get())
}
// Old version
#import "@local/typsite:0.1.0": inline

// New version
#let footnotes = state("footnotes", ())
#let inline(..args) = context {
  import "@local/typsite:0.1.0": inline
  inline(..args, footnotes: footnotes.get())
}
3.3 rule Function Signature Changes

The following functions in rule.typ rule.typ now need to receive the footnotes footnotes parameter:

  • rule-ref(footnotes) rule-ref(footnotes) instead of the old rule-ref rule-ref
  • rule-footnote(footnotes) rule-footnote(footnotes) instead of the old rule-footnote rule-footnote

In the schema schema function, you need to fetch footnotes first and then pass them to the rules:

let _footnotes = query(footnote).map(it => it.at("label", default: none)).filter(it => it != none)
show: rule-footnote(_footnotes)
show: rule-ref(_footnotes)
let _footnotes = query(footnote).map(it => it.at("label", default: none)).filter(it => it != none)
show: rule-footnote(_footnotes)
show: rule-ref(_footnotes)
4 /packages Package Migration
4.1 inline Function New footnotes Parameter

The inline inline function in @local/typsite:0.1.0 @local/typsite:0.1.0 now requires a footnotes footnotes parameter:

// Old version
inline(content, fit-font: true, scale: 100%)

// New version
inline(content, fit-font: 1em, scale: 100%, footnotes: ())
// Old version
inline(content, fit-font: true, scale: 100%)

// New version
inline(content, fit-font: 1em, scale: 100%, footnotes: ())
4.2 auto-sized-svg New fit-font Parameter

The auto-sized-svg auto-sized-svg function now has a fit-font fit-font parameter with more flexible font size control:

  • true true : Use CSS font-size inheritance
  • false false : Use fixed font-size: 1rem
  • 1em 1em : Use relative em value
5 Zed Editor Compatibility
5.1 Zed LSP Configuration

If you’re using Zed as your editor, you can add the following configuration for a better Typst development experience:

Add to .zed/settings.json .zed/settings.json :

{
  "lsp": {
    "tinymist": {
      "initialization_options": {
        "exportPdf": "never",
        "rootPath": "your/site/root/path",
      },
    },
  },
}
{
  "lsp": {
    "tinymist": {
      "initialization_options": {
        "exportPdf": "never",
        "rootPath": "your/site/root/path",
      },
    },
  },
}
5.2 VSCode Settings Migration

If you were previously using VSCode with tinymist configured, you need to update rootPath rootPath to an absolute path:

In .vscode/settings.json .vscode/settings.json :

{
  "tinymist.rootPath": "/absolute/path/to/your/site/root"
}
{
  "tinymist.rootPath": "/absolute/path/to/your/site/root"
}
6 0.1.6 Migration Link

If you’re migrating from version 0.1.6 , make sure you’ve also completed the 0.1.6 migration steps:

  • import "lib.typ" import "lib.typ" |-> import "/lib/lib.typ" import "/lib/lib.typ"
  • html-text html-text |-> html.text html.text
  • text-align text-align |-> html.align html.align
7 Other Updates
  • Added SVG anchor support, allowing creation of jumpable anchors in Typst content
  • Footnote references now support SVG inline rendering
  • Improved the font size adaptation mechanism for the inline inline function
  • Added support for more flexible fit-font fit-font parameter, allowing specific em values