Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

LaTeX & Typst (papers, theses, resumes and slides)  Module 6 – Citations and bibliographies

Typst bibliographies, Hayagriva and CSL styles

Cite with @key from a .bib or Hayagriva file in Typst, pick a built-in or CSL style, use prose and other forms, and print several bibliographies.

  • Intermediate
  • 25 minutes
  • Examples run with TeX Live 2026, TinyTeX 2026.10, Typst 0.15.1, Python 3.14.8, Pyodide 314.0.7 and poppler 26.09.0
  • By MySmartCoPilot
Free lesson, Pro answers: 25 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Load a .bib or Hayagriva file and cite its entries with @key in Typst
  • Choose a built-in citation style or load a CSL file, from the source or the command line
  • Use prose, author, year and full citations, and citations with a page
  • Split citations among several bibliographies and control how they are numbered
  • Compare Typst's output with biblatex's for the same entries, and decide how to store titles for both

Before you start

What you’ll learn · Before you start

What you will learn

  • Load a .bib or Hayagriva file and cite its entries with @key in Typst
  • Choose a built-in citation style or load a CSL file, from the source or the command line
  • Use prose, author, year and full citations, and citations with a page
  • Split citations among several bibliographies and control how they are numbered
  • Compare Typst's output with biblatex's for the same entries, and decide how to store titles for both

Before you start

On this page

Typst needs one compile and no second program to print citations and a reference list, but the same .bib file came out of its IEEE style with its titles in title case and an access date written Oct. 04, where biblatex’s IEEE style lowered the titles and wrote Oct. 4. Both are faithful to their styles; a reader of your paper sees only one of them.

Below, you will cite with @key from a .bib file and from Hayagriva: Typst's own bibliography format, a YAML file in which each entry has a type, a person is one string and a journal or book is a nested parent entry., Typst’s own format, switch among built-in styles and a CSL file written for this lesson, use the forms a citation can take, and print several bibliographies with one numbering or several. Last, the same entries go through Typst and biblatex side by side, and you will see how to store titles so that both print them right. Every run is recorded with Typst 0.15.1, and the biblatex side with Biber 2.22 from TeX Live 2026.

One compile prints the citations and the list

In Typst a citation is written like a reference, @ and the key, and #bibliography("refs.bib") both loads the data and prints the list where it stands. The default style is IEEE:

Two citations and a bibliography, and the five invented works they can cite

basic/main.typ

#set page(width: 15cm, height: auto, margin: 1cm)
Rainfall rose in the gardens @iyer2024monsoon, and a model forecast it
@sarma2023lstm.

#bibliography("refs.bib")

refs.bib

% Five invented works. Every name, title, journal, address and DOI is made up.
@article{iyer2024monsoon,
  author  = {Iyer, Kavya and Østergaard, Mikkel},
  title   = {Monsoon Rainfall Records from {Assamese} Tea Gardens},
  journal = {Journal of Invented Climate Studies},
  year    = {2024},
  volume  = {12},
  number  = {3},
  pages   = {41--58},
  doi     = {10.5555/jics.2024.0312},
}

@book{rao2021typesetting,
  author    = {Rao, Sunita},
  title     = {Typesetting for Scientists},
  publisher = {Example Academic Press},
  address   = {Pune},
  year      = {2021},
}

@inproceedings{sarma2023lstm,
  author    = {Śarmā, Anand and Okafor, Chidi},
  title     = {Forecasting Rainfall with {LSTM} Networks},
  booktitle = {Proceedings of the Fifth Workshop on Invented Data},
  year      = {2023},
  pages     = {101--110},
  doi       = {10.5555/wid.2023.101},
}

@online{rainportal2026,
  author  = {{Example Rainfall Portal}},
  title   = {Daily Rainfall Data for {Kerala}},
  url     = {https://example.com/rain/kerala},
  urldate = {2026-10-04},
  year    = {2026},
}

@dataset{rainset2025,
  author   = {Menon, Deepa and Iyer, Kavya and Okafor, Chidi and Rao, Sunita},
  title    = {Hourly Rain Gauge Readings, 2015--2024},
  year     = {2025},
  doi      = {10.5555/rain.hourly.2025},
  keywords = {data},
}
One compile, then a misspelt key and a document without a list Python · basic_session.py
from session import files, run

# One compile of main.typ prints the citations and the list, and leaves no file but the PDF; then a misspelt key, and a citation in a document that
# has no bibliography at all.
files("refs.bib", "basic/main.typ", "basic/typo.typ", "basic/no-list.typ")
run(r"""
typst compile main.typ
ls
pdftotext main.pdf - | grep .
!typst compile typo.typ
!typst compile no-list.typ
""")

Output

$ typst compile main.typ
$ ls
main.pdf
main.typ
no-list.typ
refs.bib
typo.typ
$ pdftotext main.pdf - | grep .
Rainfall rose in the gardens [1], and a model forecast it [2].
Bibliography
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[2] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110. doi:
10.5555/wid.2023.101.

$ typst compile typo.typ
error: label `<iyer2024monson>` does not exist in the document
  ┌─ typo.typ:2:29
  │
2 │ Rainfall rose in the gardens @iyer2024monson.
  │                              ^^^^^^^^^^^^^^^

[exit status 1]
$ typst compile no-list.typ
error: label `<iyer2024monsoon>` does not exist in the document
  ┌─ no-list.typ:2:29
  │
2 │ Rainfall rose in the gardens @iyer2024monsoon.
  │                              ^^^^^^^^^^^^^^^^

[exit status 1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 basic_session.py

typst compile main.typ printed [1], [2] and the list in a single run, and ls found no file beside the PDF: no .aux, .bcf or .bbl file, and no Biber. That speed comes with strictness. A key that is not in the file, @iyer2024monson, stopped the compile with label `<iyer2024monson>` does not exist in the document, and so did a correct key in a document with no bibliography, because Typst’s cite reference says that a citation needs a bibliography somewhere in the document. A LaTeX build in the same situation goes on and prints the key or [?]. The heading Bibliography comes from the title parameter, whose default, the reference page says, suits the text’s language; title: [References] changes it and title: none removes it.

Expecting a list of everything in the file

Only cited works are listed. For an entry you want in the list without citing it, write #cite(<key>, form: none); for every entry of the file, #bibliography("refs.bib", full: true).

Checkpoint

Check: Citing and printing in one compile

  1. Question 1 of 2 What did typst compile main.typ need to print the citations and the list?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: One compile, with no other program and no file left beside the PDF

    Typst reads the bibliography file, formats the citations with the style and lays out the list in the same compile.

  2. Question 2 of 2 A citation has a key that is in no bibliography file, @iyer2024monson. What does Typst do?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: It stops the compile with label <iyer2024monson> does not exist in the document

    Typst finds a missing key at once and stops, where LaTeX goes on with a placeholder; the lab's first step lists such keys before a compile.

Hayagriva is Typst’s own format

The bibliography reference describes Hayagriva as a YAML format designed for use with Typst, read by the same #bibliography call as a .bib file. Here two works of refs.bib are written in it, cited from each file in turn:

Two works in Hayagriva, and the document that cites them

hayagriva/refs.yml

# Two of refs.bib's entries in Hayagriva, Typst's own bibliography format. Invented works, as in refs.bib.
iyer2024monsoon:
  type: article
  title: Monsoon Rainfall Records from Assamese Tea Gardens
  author: ["Iyer, Kavya", "Østergaard, Mikkel"]
  date: 2024
  page-range: 41-58
  serial-number:
    doi: 10.5555/jics.2024.0312
  parent:
    type: periodical
    title: Journal of Invented Climate Studies
    volume: 12
    issue: 3

rainportal2026:
  type: web
  title: Daily Rainfall Data for Kerala
  author: Example Rainfall Portal
  date: 2026
  url:
    value: https://example.com/rain/kerala
    date: 2026-10-04

hayagriva/from-yml.typ

#set page(width: 15cm, height: auto, margin: 1cm)
Records @iyer2024monsoon and the portal @rainportal2026.
#bibliography("refs.yml")
The same two works from refs.yml and from refs.bib Python · hayagriva_session.py
from session import files, run

# The same two works cited from refs.yml (Hayagriva) and from refs.bib; diff compares the text of the two PDFs.
files("refs.bib", "hayagriva/refs.yml", "hayagriva/from-yml.typ", "hayagriva/from-bib.typ")
run(r"""
typst compile from-yml.typ
pdftotext from-yml.pdf - | grep .
typst compile from-bib.typ
pdftotext from-yml.pdf yml.txt
pdftotext from-bib.pdf bib.txt
diff yml.txt bib.txt && echo "the two PDFs hold the same text"
""")

Output

$ typst compile from-yml.typ
$ pdftotext from-yml.pdf - | grep .
Records [1] and the portal [2].
Bibliography
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[2] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
2026. [Online]. Available: https://example.com/rain/kerala

$ typst compile from-bib.typ
$ pdftotext from-yml.pdf yml.txt
$ pdftotext from-bib.pdf bib.txt
$ diff yml.txt bib.txt && echo "the two PDFs hold the same text"
the two PDFs hold the same text

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 hayagriva_session.py

diff found no difference between the two PDFs’ text, so Hayagriva is not a way to a different output; it is a different way to write the data. Set beside the .bib entry, the fields its file-format documentation describes line up like this:

In a .bib file In Hayagriva
@article{iyer2024monsoon, …} iyer2024monsoon: and type: article
journal = {…}, volume, number a parent: of type: periodical with its title, volume and issue
author = {Iyer, Kavya and Østergaard, Mikkel} author: ["Iyer, Kavya", "Østergaard, Mikkel"], one string a person
pages = {41--58} page-range: 41-58
doi = {…} serial-number: with doi: under it
year = {2024}, urldate date: 2024, and a url: with value and date

The nesting is the point of the format: a journal, a book or a website is a parent entry with fields of its own, and a person is one string, so no and can split an organisation. Choose Hayagriva for a project that only Typst reads; keep a .bib file when the same data must also feed BibTeX, Biber or a reference manager.

Checkpoint

Check: Hayagriva files

  1. One question In refs.yml, where does the name of the article's journal go?

    Choose one answer.

    Show the answer: One question

    Answer: In a parent entry of type periodical, as its title, with the volume and issue

    Hayagriva nests a work inside the work that contains it: an article in a periodical, a chapter in a book.

A style is a name or a CSL file

The style parameter takes a built-in style’s name or a path to a CSL: Citation Style Language: an XML format for citation styles. A CSL file describes how citations and the reference list look, and Typst, Zotero and other programs read it. file, and the reference page lists the built-in names, some twice, under a full name and a short alias such as apa and ieee. To switch styles without editing the document, styles.typ reads its style from the command line through sys.inputs, which holds what --input key=value passes:

A document that takes its style from --input, and a small CSL style

styles/styles.typ

#set page(width: 15cm, height: auto, margin: 1cm)
// The style comes from the command line: typst compile --input style=apa styles.typ
#let style = sys.inputs.at("style", default: "ieee")
Rainfall rose @iyer2024monsoon, as #cite(<sarma2023lstm>, form: "prose") predicted from
hourly readings @rainset2025.
#bibliography("refs.bib", style: style)

styles/rain-short.csl

<?xml version="1.0" encoding="utf-8"?>
<!-- A small author-date style written for this lesson: short names and the year in citations,
     then surname, initials, year and the title in italics in the list. -->
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0">
  <info>
    <title>Rain report, short author-date</title>
    <id>https://example.com/csl/rain-report-short</id>
    <updated>2026-01-01T00:00:00+00:00</updated>
  </info>
  <citation>
    <layout prefix="(" suffix=")" delimiter="; ">
      <group delimiter=" ">
        <names variable="author">
          <name form="short" and="symbol" et-al-min="3" et-al-use-first="1"/>
        </names>
        <date variable="issued">
          <date-part name="year"/>
        </date>
      </group>
    </layout>
  </citation>
  <bibliography>
    <sort>
      <key variable="author"/>
    </sort>
    <layout suffix=".">
      <group delimiter=". ">
        <names variable="author">
          <name name-as-sort-order="all" initialize-with="." delimiter=", " and="symbol"/>
        </names>
        <date variable="issued">
          <date-part name="year"/>
        </date>
        <text variable="title" font-style="italic"/>
      </group>
    </layout>
  </bibliography>
</style>
One source in IEEE, APA, Chicago author-date and rain-short.csl Python · styles_session.py
from session import files, run

# styles.typ reads its style name from --input, so one source prints in IEEE, APA, Chicago author-date and a CSL
# file of this lesson; then a style name Typst 0.15 has renamed, and one it does not know.
files("refs.bib", "styles/styles.typ", "styles/rain-short.csl")
run(r"""
typst compile --input style=ieee styles.typ ieee.pdf
pdftotext ieee.pdf - | grep .
typst compile --input style=apa styles.typ apa.pdf
pdftotext apa.pdf - | grep .
typst compile --input style=chicago-author-date styles.typ chicago.pdf
pdftotext chicago.pdf - | grep .
typst compile --input style=rain-short.csl styles.typ own.pdf
pdftotext own.pdf - | grep .
typst compile --input style=vancouver styles.typ vancouver.pdf
!typst compile --input style=ieee-transactions styles.typ unknown.pdf
""")

Output

$ typst compile --input style=ieee styles.typ ieee.pdf
$ pdftotext ieee.pdf - | grep .
Rainfall rose [1], as A. Śarmā and C. Okafor [2] predicted from hourly readings
[3].
Bibliography
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[2] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110. doi:
10.5555/wid.2023.101.
[3] D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly Rain Gauge Readings, 2015–
2024. (2025). doi: 10.5555/rain.hourly.2025.

$ typst compile --input style=apa styles.typ apa.pdf
$ pdftotext apa.pdf - | grep .
Rainfall rose (Iyer & Østergaard, 2024), as Śarmā & Okafor (2023) predicted from
hourly readings (Menon et al., 2025).
Bibliography
Iyer, K., & Østergaard, M. (2024). Monsoon Rainfall Records from Assamese Tea
Gardens. Journal of Invented Climate Studies, 12(3), 41–58. https://doi.org/10.
5555/jics.2024.0312
Menon, D., Iyer, K., Okafor, C., & Rao, S. (2025). Hourly Rain Gauge Readings,
2015–2024 [Computer software]. https://doi.org/10.5555/rain.hourly.2025
Śarmā, A., & Okafor, C. (2023). Forecasting Rainfall with LSTM Networks.
Proceedings of the Fifth Workshop on Invented Data, 101–110. https://doi.org/
10.5555/wid.2023.101

$ typst compile --input style=chicago-author-date styles.typ chicago.pdf
$ pdftotext chicago.pdf - | grep .
Rainfall rose (Iyer and Østergaard 2024), as Śarmā and Okafor (2023) predicted
from hourly readings (Menon et al. 2025).
Bibliography
Iyer, Kavya, and Mikkel Østergaard. 2024. “Monsoon Rainfall Records from
Assamese Tea Gardens.” Journal of Invented Climate Studies 12 (3): 41–58.
https://doi.org/10.5555/jics.2024.0312.
Menon, Deepa, Kavya Iyer, Chidi Okafor, and Sunita Rao. 2025. Hourly Rain
Gauge Readings, 2015–2024. Released. https://doi.org/10.5555/rain.hourly.2025.
Śarmā, Anand, and Chidi Okafor. 2023. “Forecasting Rainfall with LSTM
Networks.” In “Proceedings of the Fifth Workshop on Invented Data.” Special
issue, Proceedings of the Fifth Workshop on Invented Data, 101–10. https://doi.
org/10.5555/wid.2023.101.

$ typst compile --input style=rain-short.csl styles.typ own.pdf
$ pdftotext own.pdf - | grep .
Rainfall rose (Iyer & Østergaard 2024), as Śarmā & Okafor (2023) predicted from
hourly readings (Menon et al. 2025).
Bibliography
Iyer, K. & Østergaard, M. 2024. Monsoon Rainfall Records from Assamese Tea
Gardens.
Menon, D., Iyer, K., Okafor, C., & Rao, S. 2025. Hourly Rain Gauge Readings, 2015–
2024.
Śarmā, A. & Okafor, C. 2023. Forecasting Rainfall with LSTM Networks.

$ typst compile --input style=vancouver styles.typ vancouver.pdf
warning: style `"vancouver"` has been deprecated in favor of `"nlm-citation-sequence"`
  ┌─ styles.typ:6:33
  │
6 │ #bibliography("refs.bib", style: style)
  │                                  ^^^^^

$ typst compile --input style=ieee-transactions styles.typ unknown.pdf
error: unknown style: ieee-transactions
  ┌─ styles.typ:6:33
  │
6 │ #bibliography("refs.bib", style: style)
  │                                  ^^^^^

[exit status 1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 styles_session.py

The four builds printed the same three works four ways. IEEE gave [1] to [3] in order of citation with initials; APA and Chicago author-date gave the names and years, (Iyer & Østergaard, 2024) and (Iyer and Østergaard 2024), sorted the list by name, and wrote DOIs as https://doi.org/ addresses. rain-short.csl is a CSL file written for this lesson: the specification asks for a <style> root with its class and version, an <info> block with a title, an id and an update time, and a <citation> with a <layout>, and lets a <bibliography> follow. Its citation layout put names and year in parentheses and its et-al-min="3" shortened the four people of the dataset to Menon et al. 2025, so a journal’s own CSL file works the same way: save it next to the document and give its path.

Two last commands show what Typst 0.15 does with style names. vancouver still worked but warned that it has been deprecated in favor of "nlm-citation-sequence", one of the renames of the 0.15.0 changelog, made to follow the CSL project’s names; an unknown name, ieee-transactions, stopped with unknown style.

Proof-read a style you have not used before

The APA build labelled the dataset [Computer software], and Chicago printed Released. for it and named the paper’s proceedings twice, the second time after Special issue. A style is a program that reads your data its own way: read every list once in each style a document uses.

Checkpoint

Check: Built-in styles and CSL files

  1. Question 1 of 2 A journal gives you its style as journal.csl. How do you use it in Typst?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Save it next to the document and write #bibliography("refs.bib", style: "journal.csl")

    A built-in name or a path to a CSL file: the same parameter takes both, and --input with sys.inputs can choose either from the command line.

  2. Question 2 of 2 What did Typst 0.15.1 do with style: "vancouver"?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: It compiled and warned that the style is deprecated in favour of nlm-citation-sequence

    Read Typst's warnings after an update: renamed styles still work for now, under a warning that names the new one.

Forms change what a citation prints

@key prints the style’s normal citation. #cite takes a form for the other uses a sentence has, and @key[…] adds a supplement, such as a page. The same seven citations in APA and in IEEE:

forms.typ: seven citations in a numbered list TYP · forms/forms.typ
#set page(width: 15cm, height: auto, margin: 1cm)
#let style = sys.inputs.at("style", default: "apa")
+ normal: rainfall rose @iyer2024monsoon.
+ with a page: rainfall rose @iyer2024monsoon[p. 45].
+ two at once: rainfall rose @iyer2024monsoon @rao2021typesetting.
+ prose: #cite(<sarma2023lstm>, form: "prose") trained a model.
+ author and year: #cite(<rao2021typesetting>, form: "author") wrote it in #cite(<rao2021typesetting>, form: "year").
+ full: #cite(<rao2021typesetting>, form: "full")
+ listed, not printed: the portal#cite(<rainportal2026>, form: none) is open.

#bibliography("refs.bib", style: style)
The seven citations in APA and IEEE Python · forms_session.py
from session import files, run

# Seven citations of forms.typ in APA, then in IEEE: the style decides how each form looks.
files("refs.bib", "forms/forms.typ")
run(r"""
typst compile --input style=apa forms.typ apa.pdf
pdftotext apa.pdf - | grep .
typst compile --input style=ieee forms.typ ieee.pdf
pdftotext ieee.pdf - | grep .
""")

Output

$ typst compile --input style=apa forms.typ apa.pdf
$ pdftotext apa.pdf - | grep .
1. normal: rainfall rose (Iyer & Østergaard, 2024).
2. with a page: rainfall rose (Iyer & Østergaard, 2024, p. 45).
3. two at once: rainfall rose (Iyer & Østergaard, 2024; Rao, 2021).
4. prose: Śarmā & Okafor (2023) trained a model.
5. author and year: Rao wrote it in 2021.
6. full: Rao, S. (2021). Typesetting for Scientists. Example Academic Press.
7. listed, not printed: the portal is open.
Bibliography
Example Rainfall Portal. (2026,). Daily Rainfall Data for Kerala. https://example.
com/rain/kerala
Iyer, K., & Østergaard, M. (2024). Monsoon Rainfall Records from Assamese Tea
Gardens. Journal of Invented Climate Studies, 12(3), 41–58. https://doi.org/10.
5555/jics.2024.0312
Rao, S. (2021). Typesetting for Scientists. Example Academic Press.
Śarmā, A., & Okafor, C. (2023). Forecasting Rainfall with LSTM Networks.
Proceedings of the Fifth Workshop on Invented Data, 101–110. https://doi.org/
10.5555/wid.2023.101

$ typst compile --input style=ieee forms.typ ieee.pdf
$ pdftotext ieee.pdf - | grep .
1. normal: rainfall rose [1].
2. with a page: rainfall rose [1, p. 45].
3. two at once: rainfall rose [1], [2].
4. prose: A. Śarmā and C. Okafor [3] trained a model.
5. author and year: S. Rao wrote it in 2021.
6. full: [2] S. Rao, Typesetting for Scientists. Pune: Example Academic Press, 2021.
7. listed, not printed: the portal is open.
Bibliography
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[2] S. Rao, Typesetting for Scientists. Pune: Example Academic Press, 2021.
[3] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110. doi:
10.5555/wid.2023.101.
[4] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
2026. [Online]. Available: https://example.com/rain/kerala

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 forms_session.py

Written APA printed IEEE printed
@iyer2024monsoon (Iyer & Østergaard, 2024) [1]
@iyer2024monsoon[p. 45] (Iyer & Østergaard, 2024, p. 45) [1, p. 45]
@iyer2024monsoon @rao2021typesetting (Iyer & Østergaard, 2024; Rao, 2021) [1], [2]
#cite(<sarma2023lstm>, form: "prose") Śarmā & Okafor (2023) A. Śarmā and C. Okafor [3]
form: "author" and form: "year" Rao and 2021 S. Rao and 2021
form: "full" the whole entry the whole entry, with its number
form: none nothing; the portal is still listed nothing; still listed as [4]

The cite reference describes prose as the form for weaving a citation into the text, the counterpart of biblatex’s \textcite and natbib’s \citet; #set cite(form: "prose") would make it the default for what follows. Two adjacent citations, separated by a space, became one parenthesis in APA and two brackets in IEEE. Note the & in APA’s prose form: biblatex-apa’s \textcite printed Śarmā and Okafor (2023) in this module’s biblatex lesson, so check which your style guide wants in running text.

A key with a slash in angle brackets

#cite(<my/key-2020>) is not a valid label. The cite reference says to write a key with such characters as #cite(label("my/key-2020")).

Checkpoint

Check: Citation forms and supplements

  1. Question 1 of 2 What did #cite(<sarma2023lstm>, form: "prose") print in the IEEE style?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: A. Śarmā and C. Okafor [3]

    The form says how the citation is used; the style decides how it looks. Prose is Typst's counterpart of \textcite and \citet.

  2. Question 2 of 2 How do you cite page 45 of iyer2024monsoon in Typst?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: @iyer2024monsoon[p. 45]

    @key[…] adds a supplement; #cite(<key>, supplement: […]) is the same in function form.

Several bibliographies, one numbering or several

Typst 0.15 lets a document hold several bibliographies, its changelog says, and gives each citation to exactly one. The bibliography reference gives the order of the rules: the first list whose target selects the citation; otherwise the nearest following list without a target of its own that holds its key; otherwise the nearest preceding such list. A second parameter, group, decides which lists share their numbers. Three files try the rules:

A list per chapter, the same with group: none, and a box with a list of its own

several/by-chapter.typ

#set page(width: 15cm, height: auto, margin: 1cm)
= Rain
Records @iyer2024monsoon and a model @sarma2023lstm.
#bibliography("refs.bib", title: [Sources for Rain])

= Data
The portal @rainportal2026 and the readings @rainset2025.
#bibliography("refs.bib", title: [Sources for Data])

several/restart.typ

#set page(width: 15cm, height: auto, margin: 1cm)
#set bibliography(group: none)
= Rain
Records @iyer2024monsoon and a model @sarma2023lstm.
#bibliography("refs.bib", title: [Sources for Rain])

= Data
The portal @rainportal2026 and the readings @rainset2025.
#bibliography("refs.bib", title: [Sources for Data])

several/datasets.typ

#set page(width: 15cm, height: auto, margin: 1cm)
// A box with a list of its own: the context block is the box, so here() is the box and the list takes only the
// citations inside it.
#let data-box(body) = context block(stroke: 0.5pt, inset: 6pt)[
  #body
  #bibliography("refs.bib", title: [Datasets and web pages], target: selector(cite).within(here()))
]
= Report
Records @iyer2024monsoon and a model @sarma2023lstm.
#data-box[The readings @rainset2025 and the portal @rainportal2026.]
#bibliography("refs.bib", title: [Works cited])
Which list took each citation, and its number Python · several_session.py
from session import files, run

# Two lists that each take the citations before them (numbers continue), the same with group: none (numbers restart),
# and a list that takes only the citations inside its box through target.
files("refs.bib", "several/by-chapter.typ", "several/restart.typ", "several/datasets.typ")
run(r"""
typst compile by-chapter.typ
pdftotext by-chapter.pdf - | grep -E "^\[|^Records|^The portal|^Sources"
typst compile restart.typ
pdftotext restart.pdf - | grep -E "^\[|^Records|^The portal|^Sources"
typst compile datasets.typ
pdftotext datasets.pdf - | grep .
""")

Output

$ typst compile by-chapter.typ
$ pdftotext by-chapter.pdf - | grep -E "^\[|^Records|^The portal|^Sources"
Records [1] and a model [2].
Sources for Rain
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
[2] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
The portal [3] and the readings [4].
Sources for Data
[3] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
[4] D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly Rain Gauge Readings, 2015–
$ typst compile restart.typ
$ pdftotext restart.pdf - | grep -E "^\[|^Records|^The portal|^Sources"
Records [1] and a model [2].
Sources for Rain
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
[2] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
The portal [1] and the readings [2].
Sources for Data
[1] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
[2] D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly Rain Gauge Readings, 2015–
$ typst compile datasets.typ
$ pdftotext datasets.pdf - | grep .
Report
Records [3] and a model [4].
The readings [1] and the portal [2].
Datasets and web pages
[1] D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly Rain Gauge Readings,
2015–2024. (2025). doi: 10.5555/rain.hourly.2025.
[2] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
2026. [Online]. Available: https://example.com/rain/kerala
Works cited
[3] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[4] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110. doi:
10.5555/wid.2023.101.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 several_session.py

Follow the citations through the rules:

Interactive · stage by stage Which list takes a citation? Follow citations of the lesson's files through Typst's rules and see which list prints each one, under which number.
Which list takes a citation?, step 7 of 7. Showing A citation, @key (@iyer2024monsoon, before), A list that targets it (Datasets and web pages), Next list with the key (Works cited: [3]), Previous list with key, No list has the key. In focus: No list has the key.no target anywhereA citation, @key@iyer2024monsoon, beforeA list that targets itDatasets and web pagesNext list with the keyWorks cited: [3]Previous list with keybefore the citationNo list has the keythe compile stops

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. No target anywhere. In by-chapter.typ no list has a target, so @iyer2024monsoon, in the Rain chapter, goes to the first list after it that holds its key, Sources for Rain.
  2. Numbers continue. @rainportal2026 in the Data chapter goes to Sources for Data. Both lists are in the default group, so they share one numbering and it became [3].
  3. A group of its own. With #set bibliography(group: none), in restart.typ, each list numbers on its own, and the same citation became [1] in Sources for Data.
  4. A list with a target. In datasets.typ, the box's list has target: selector(cite).within(here()), so it takes the two citations inside the box, @rainset2025 and @rainportal2026, as [1] and [2].
  5. The rest go on. The two citations before the box are not selected by its target, so they go to the next list without one, Works cited, as [3] and [4]. The numbers follow the order of the lists, not of the text.
  6. Looking back. A citation with no list after it that holds its key goes to the nearest list before it that does; the reference page gives this as the last rule.
  7. No list at all. In no-list.typ, which has no bibliography, @iyer2024monsoon stopped the compile with the error that the label <iyer2024monsoon> does not exist in the document.

With lists in the default group, numbers continued from chapter to chapter, [3] and [4] in the second; #set bibliography(group: none) made each list start at [1]. The box of datasets.typ took its own citations through target: selector(cite).within(here()), inside a context block, because here() is a contextual function, which its reference says can only be used when the context is known. Its list printed first, so its works took [1] and [2], and the citations before the box became [3] and [4]: the numbers follow the lists, not the text. That is correct by the rules and odd to read, so give such a box group: none, or put lists in the order a reader meets them.

Key idea

Each citation goes to one list, by target first and then the nearest list that holds its key, and the lists of a group share one numbering in the order they are printed.

Checkpoint

Check: Several bibliographies and their numbering

  1. Question 1 of 2 In by-chapter.typ, neither list has a target. Which list takes @rainportal2026, cited in the Data chapter?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Sources for Data, the nearest list after the citation that holds the key

    Target first, then the nearest following list that holds the key, then the nearest preceding one.

  2. Question 2 of 2 In restart.typ, #set bibliography(group: none) stands before both lists. What changed?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Each list numbered its works from [1]

    Lists in the default group share one numbering; group none, or a group name of their own, separates them.

The same .bib file, printed by Typst and by biblatex

Typst reads .bib files with its own parser and formats them with CSL styles, so the same entries do not print the same as with Biber and a biblatex style. The four citations of refs.bib in biblatex’s IEEE style, the biblatex-ieee package, and in Typst’s, then the article stored in sentence case and printed by four Typst styles:

The same citations for biblatex and Typst, and the article in sentence case

compare/compare.tex

\documentclass{article}
\usepackage[style=ieee,backend=biber]{biblatex}
\addbibresource{refs.bib}
\begin{document}
Records \autocite{iyer2024monsoon}, a model \autocite{sarma2023lstm}, the portal \autocite{rainportal2026}
and the readings \autocite{rainset2025}.
\printbibliography
\end{document}

compare/compare.typ

#set page(width: 15cm, height: auto, margin: 1cm)
Records @iyer2024monsoon, a model @sarma2023lstm, the portal @rainportal2026
and the readings @rainset2025.
#bibliography("refs.bib", style: "ieee")

compare/sentence.bib

% The article of refs.bib with its title in sentence case: capitals only where the title needs them, braced.
@article{iyer2024monsoon,
  author  = {Iyer, Kavya and Østergaard, Mikkel},
  title   = {Monsoon rainfall records from {Assamese} tea gardens},
  journal = {Journal of Invented Climate Studies},
  year    = {2024},
  volume  = {12},
  number  = {3},
  pages   = {41--58},
}
biblatex's IEEE against Typst's, then sentence case in four styles Python · compare_session.py
from session import files, run

# The same four citations of refs.bib in biblatex's IEEE style and in Typst's, then the article stored in sentence
# case, printed by four of Typst's styles.
files("refs.bib", "compare/compare.tex", "compare/compare.typ", "compare/sentence.bib", "compare/sentence.typ")
run(r"""
pdflatex -interaction=nonstopmode compare.tex | grep -E "Output"
biber compare | grep -E "Found [0-9]+ citekeys"
pdflatex -interaction=nonstopmode compare.tex | grep -E "Output"
pdftotext compare.pdf - | grep .
typst compile compare.typ
pdftotext compare.pdf - | grep .
typst compile --input style=ieee sentence.typ s-ieee.pdf
pdftotext s-ieee.pdf - | grep .
typst compile --input style=apa sentence.typ s-apa.pdf
pdftotext s-apa.pdf - | grep .
typst compile --input style=chicago-author-date sentence.typ s-chicago.pdf
pdftotext s-chicago.pdf - | grep .
typst compile --input style=mla sentence.typ s-mla.pdf
pdftotext s-mla.pdf - | grep .
""")

Output

$ pdflatex -interaction=nonstopmode compare.tex | grep -E "Output"
Output written on compare.pdf (1 page, 28302 bytes).
$ biber compare | grep -E "Found [0-9]+ citekeys"
INFO - Found 4 citekeys in bib section 0
$ pdflatex -interaction=nonstopmode compare.tex | grep -E "Output"
Output written on compare.pdf (1 page, 70444 bytes).
$ pdftotext compare.pdf - | grep .
Records [1], a model [2], the portal [3] and the readings [4].
References
[1]
K. Iyer and M. Østergaard, “Monsoon rainfall records from Assamese tea
gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58,
2024. doi: 10.5555/jics.2024.0312
[2]
A. Śarmā and C. Okafor, “Forecasting rainfall with LSTM networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110.
doi: 10.5555/wid.2023.101
[3]
Example Rainfall Portal. “Daily rainfall data for Kerala,” Accessed: Oct. 4,
2026. [Online]. Available: https://example.com/rain/kerala
[4]
D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly rain gauge readings,
2015–2024, 2025. doi: 10.5555/rain.hourly.2025
1

$ typst compile compare.typ
$ pdftotext compare.pdf - | grep .
Records [1], a model [2], the portal [3] and the readings [4].
Bibliography
[1] K. Iyer and M. Østergaard, “Monsoon Rainfall Records from Assamese Tea
Gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024,
doi: 10.5555/jics.2024.0312.
[2] A. Śarmā and C. Okafor, “Forecasting Rainfall with LSTM Networks,” in
Proceedings of the Fifth Workshop on Invented Data, 2023, pp. 101–110. doi:
10.5555/wid.2023.101.
[3] Example Rainfall Portal, “Daily Rainfall Data for Kerala.” Accessed: Oct. 04,
2026. [Online]. Available: https://example.com/rain/kerala
[4] D. Menon, K. Iyer, C. Okafor, and S. Rao, Hourly Rain Gauge Readings, 2015–
2024. (2025). doi: 10.5555/rain.hourly.2025.

$ typst compile --input style=ieee sentence.typ s-ieee.pdf
$ pdftotext s-ieee.pdf - | grep .
[1] K. Iyer and M. Østergaard, “Monsoon rainfall records from Assamese tea
gardens,” Journal of Invented Climate Studies, vol. 12, no. 3, pp. 41–58, 2024.

$ typst compile --input style=apa sentence.typ s-apa.pdf
$ pdftotext s-apa.pdf - | grep .
Iyer, K., & Østergaard, M. (2024). Monsoon rainfall records from Assamese tea
gardens. Journal of Invented Climate Studies, 12(3), 41–58.

$ typst compile --input style=chicago-author-date sentence.typ s-chicago.pdf
$ pdftotext s-chicago.pdf - | grep .
Iyer, Kavya, and Mikkel Østergaard. 2024. “Monsoon Rainfall Records from
Assamese Tea Gardens.” Journal of Invented Climate Studies 12 (3): 41–58.

$ typst compile --input style=mla sentence.typ s-mla.pdf
$ pdftotext s-mla.pdf - | grep .
Iyer, Kavya, and Mikkel Østergaard. “Monsoon Rainfall Records from Assamese
Tea Gardens.” Journal of Invented Climate Studies, vol. 12, no. 3, 2024, pp. 41–
58.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 compare_session.py

In the list biblatex ieee Typst ieee
Heading References Bibliography
The article’s title Monsoon rainfall records from Assamese tea gardens Monsoon Rainfall Records from Assamese Tea Gardens
The web page’s access date Accessed: Oct. 4, 2026 Accessed: Oct. 04, 2026
The web page Example Rainfall Portal. “Daily rainfall data for Kerala,” Example Rainfall Portal, “Daily Rainfall Data for Kerala.”
The dataset Hourly rain gauge readings, 2015–2024, 2025. Hourly Rain Gauge Readings, 2015–2024. (2025).
A DOI at the end doi: 10.5555/jics.2024.0312 doi: 10.5555/jics.2024.0312.

The biggest difference is the case of titles, and the CSL specification explains it. It marks sentence-case conversion as deprecated and advises storing titles in sentence case, because a program can turn sentence case into title case reliably but cannot find the proper nouns to go the other way. So Typst’s styles print a title as stored, and only turn it into title case where the style asks for title case. The sentence-case file proved it: IEEE and APA printed Monsoon rainfall records from Assamese tea gardens, Chicago and MLA Monsoon Rainfall Records from Assamese Tea Gardens, all from one stored form with the proper noun braced.

One .bib file for biblatex and Typst

Store titles in sentence case and brace proper nouns and acronyms, Monsoon rainfall records from {Assamese} tea gardens. biblatex’s sentence-case styles and Typst’s print it right, and Typst’s title-case styles convert it. Then proof-read each list once, as the dataset and the access date show.

Checkpoint

Check: Typst against biblatex, and titles for both

  1. One question The article's title stored in sentence case, Monsoon rainfall records from {Assamese} tea gardens, went through four Typst styles. What did Chicago author-date print?

    Choose one answer.

    Show the answer: One question

    Answer: Monsoon Rainfall Records from Assamese Tea Gardens

    Store titles in sentence case with braced proper nouns: styles that want title case convert it, and the others print it as stored.

Practise: check a Typst document’s citations

Two small functions cover what this lesson did by hand: finding the keys a Typst document cites that no bibliography file holds, before the compile stops on them, and turning a .bib article into a Hayagriva entry. Their sample tests use this lesson’s files, typo.typ among them, and the first hint of each step is open:

Code lab · 2 steps

Check a Typst document's citations

List the keys a Typst document cites that its bibliography file lacks, then convert a .bib article into a Hayagriva entry.

  1. Find the citations a Typst compile will stop on To do
  2. Turn a .bib article into a Hayagriva entry To do

Exercise · Medium · Python

Find the citations a Typst compile will stop on

In the lesson, @iyer2024monson, one letter short, stopped the compile with `label <iyer2024monson> does not exist`. A check before the compile can list every such key at once.

Write missing_keys(source, keys) in missing.py. Given the text of a Typst file and the set of keys its bibliography file holds, it returns, in order of first appearance and each once, the cited keys that are neither in keys nor labels the document defines itself. Count as citations:

  • @name, where a name is letters, digits, _, -, : and ., without a . or : at its end, which belongs to the sentence: @iyer2024monsoon. cites iyer2024monsoon; a supplement after it, @iyer2024monsoon[p. 45], is not part of the name;
  • #cite(<name>, …).

A label the document defines is a <name> written in the text, such as = Data <data>; then @data is a reference to that heading, not a citation. The <name> inside #cite(…) defines nothing.

Starter code · missing.py

import re


def missing_keys(source, keys):
    """Return the cited keys of a Typst source that are neither in `keys` nor labels it defines, in order, once each."""
    # Replace this line: find @name and #cite(<name>) citations, and the <name> labels the text defines.
    return []
The sample tests · test_missing.py
from missing import missing_keys

KEYS = {"iyer2024monsoon", "sarma2023lstm", "rao2021typesetting", "rainportal2026", "rainset2025"}


def test_the_lessons_typo():
    """finds the misspelt key of typo.typ"""
    source = "Rainfall rose in the gardens @iyer2024monson.\n\n#bibliography(\"refs.bib\")\n"
    assert missing_keys(source, KEYS) == ["iyer2024monson"]


def test_all_present():
    """finds nothing when every key is in the file"""
    source = "Rainfall rose @iyer2024monsoon[p. 45], as #cite(<sarma2023lstm>, form: \"prose\") predicted.\n"
    assert missing_keys(source, KEYS) == []


def test_cite_call():
    """reads the key of a cite call"""
    assert missing_keys("as #cite(<okafor2022rain>, form: \"author\") wrote", KEYS) == ["okafor2022rain"]


def test_heading_label_is_not_a_citation():
    """leaves out a reference to a label the document defines"""
    source = "= Data <data>\nSee @data, and the readings @rainset2025.\n"
    assert missing_keys(source, KEYS) == []


def test_sentence_end():
    """does not take a full stop or a colon into the key"""
    assert missing_keys("as shown by @menon2025gauges: rain rose.", KEYS) == ["menon2025gauges"]


def test_each_once_in_order():
    """reports each missing key once, in order of first appearance"""
    source = "@zeta2020 and @alpha2021, then @zeta2020 again, and #cite(<alpha2021>)."
    assert missing_keys(source, KEYS) == ["zeta2020", "alpha2021"]
A hint

Work in three passes. Collect the keys of #cite(<…> and blank those calls out of the text with re.sub; collect the labels the rest defines with <([\w:.-]+)>; then go through the @ references and the cite keys in order of position, with rstrip(".:") on each @ name.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Exercise · Medium · Python

Turn a .bib article into a Hayagriva entry

The lesson's refs.yml holds the article of refs.bib in Hayagriva's shape: the journal is a parent of type periodical, each person is a string, and the DOI is a serial number. Write article(fields) in hayagriva.py. Given the fields of a .bib article as a dictionary of strings, it returns the Hayagriva entry as a dictionary:

  • type is "article", and title and date (from year) are copied;
  • author is the list of names, split at and between spaces outside braces, each without its outer braces, so that {Example Rainfall Portal} becomes Example Rainfall Portal, while a name with braces inside it, such as {\O}stergaard, Mikkel, keeps them;
  • page-range is pages with -- written as -;
  • serial-number is {"doi": …} when there is a DOI;
  • parent is {"type": "periodical", "title": …} from journal (or journaltitle), with volume, and issue from number, when they are there.

A field the entry lacks is left out, not given as an empty string.

Starter code · hayagriva.py

import re


def article(fields):
    """Return the Hayagriva entry of a .bib article given as a dictionary of its fields."""
    # Replace this line: build type, title, author, date, page-range, serial-number and parent from the fields.
    return {"type": "article"}
The sample tests · test_hayagriva.py
from hayagriva import article

IYER = {
    "author": "Iyer, Kavya and Østergaard, Mikkel",
    "title": "Monsoon Rainfall Records from {Assamese} Tea Gardens",
    "journal": "Journal of Invented Climate Studies",
    "year": "2024",
    "volume": "12",
    "number": "3",
    "pages": "41--58",
    "doi": "10.5555/jics.2024.0312",
}


def test_the_lessons_article():
    """converts the article of refs.bib"""
    assert article(IYER) == {
        "type": "article",
        "title": "Monsoon Rainfall Records from {Assamese} Tea Gardens",
        "author": ["Iyer, Kavya", "Østergaard, Mikkel"],
        "date": "2024",
        "page-range": "41-58",
        "serial-number": {"doi": "10.5555/jics.2024.0312"},
        "parent": {"type": "periodical", "title": "Journal of Invented Climate Studies", "volume": "12", "issue": "3"},
    }


def test_missing_fields_are_left_out():
    """leaves out the fields an entry lacks"""
    fields = {"author": "Thomas, Ruth", "title": "Long Spells", "journal": "Invented Weather Letters", "year": "2018"}
    assert article(fields) == {
        "type": "article",
        "title": "Long Spells",
        "author": ["Thomas, Ruth"],
        "date": "2018",
        "parent": {"type": "periodical", "title": "Invented Weather Letters"},
    }


def test_journaltitle_alias():
    """reads the journal from journaltitle too"""
    fields = {"author": "Shah, Meera", "title": "Wet Spells", "journaltitle": "Invented Weather Letters", "year": "2020"}
    assert article(fields)["parent"] == {"type": "periodical", "title": "Invented Weather Letters"}


def test_braced_organisation():
    """removes the outer braces of an organisation"""
    fields = {"author": "{Example Rainfall Portal} and Menon, Deepa", "title": "Gauges", "journal": "J", "year": "2026"}
    assert article(fields)["author"] == ["Example Rainfall Portal", "Menon, Deepa"]


def test_braces_inside_a_name():
    """keeps braces that belong to a name, such as a LaTeX accent"""
    fields = {"author": "{\\O}stergaard, Mikkel and Iyer, Kavya", "title": "Short Spells", "journal": "J", "year": "2017"}
    assert article(fields)["author"] == ["{\\O}stergaard, Mikkel", "Iyer, Kavya"]


def test_single_page():
    """keeps a single page as it is"""
    fields = {"author": "Rao, Sunita", "title": "Notes", "journal": "J", "year": "2021", "pages": "7"}
    assert article(fields)["page-range"] == "7"
A hint

Build the dictionary step by step and add a key only if its field is present. For the names, split with re.split(r"\s+and\s+", author) (the tests put no and inside braces), then take the braces off each name that both starts with { and ends with }.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Last, the questions on Typst’s bibliographies, Hayagriva, styles, forms, several lists and the comparison with biblatex: every one explains its answer, and the session starts with your weakest idea:

Practice that adapts to you

Practise this lesson

18 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 18 What does #bibliography("refs.bib") do in a Typst document?

    Choose one answer.

    Show the answer: Question 1 of 18

    Answer: It loads the entries of refs.bib and prints the list of cited works where it stands

    The call is the data and the list at once; style, title, full, target and group change what it prints.

  2. Question 2 of 18 The list must have no heading, because the document puts its own above it. What do you write?

    Choose one answer.

    Show the answer: Question 2 of 18

    Answer: #bibliography("refs.bib", title: none)

    title takes auto, none or your own content, such as [References].

  3. Question 3 of 18 One work must appear in the list without a citation in the text. What do you write, and what does it print?

    Choose one answer.

    Show the answer: Question 3 of 18

    Answer: #cite(<rainportal2026>, form: none), which prints nothing in the text and lists the work

    form none is Typst's counterpart of \nocite{key}, and full true of \nocite{*}.

  4. Question 4 of 18 How does a Hayagriva file write the two authors of the article?

    Choose one answer.

    Show the answer: Question 4 of 18

    Answer: As a list of strings, author: ["Iyer, Kavya", "Østergaard, Mikkel"]

    A list of names cannot be split in the wrong place, which is one reason to write Hayagriva by hand.

  5. Question 5 of 18 Two documents cited the same two works from refs.yml and from refs.bib. What did diff find in the text of their PDFs?

    Choose one answer.

    Show the answer: Question 5 of 18

    Answer: No difference at all

    The file format changes how you write the data, not what the style prints.

  6. Question 6 of 18 A thesis is written in Typst, but its references also feed a LaTeX paper and come from Zotero. Which file format do you keep?

    Choose one answer.

    Show the answer: Question 6 of 18

    Answer: A .bib file, which Typst, BibTeX, Biber and Zotero all read

    Choose the format by every program that must read the data, not only by the one you write in.

  7. Question 7 of 18 Which style does Typst use when #bibliography is given none?

    Choose one answer.

    Show the answer: Question 7 of 18

    Answer: IEEE

    Name the style your guide asks for explicitly, even when it is the default, so the source says what it prints.

  8. Question 8 of 18 styles.typ sets #let style = sys.inputs.at("style", default: "ieee"). What does typst compile styles.typ with no input print?

    Choose one answer.

    Show the answer: Question 8 of 18

    Answer: The IEEE style, the default given to at

    --input key=value makes the value available as a string in sys.inputs, and at with a default keeps the document working without it.

  9. Question 9 of 18 A report switches from IEEE to APA in Typst, and the list now calls a dataset [Computer software]. What does that tell you to do?

    Choose one answer.

    Show the answer: Question 9 of 18

    Answer: Read the whole list in every style the document uses, and correct or change the entry type where a style misreads it

    A new style is new output from the same data. Proof-read it once, as you would a new printer.

  10. Question 10 of 18 Which form prints only the year of a work?

    Choose one answer.

    Show the answer: Question 10 of 18

    Answer: form: "year"

    normal, prose, author, year, full and none: the forms of the cite reference.

  11. Question 11 of 18 How did @iyer2024monsoon @rao2021typesetting, two citations side by side, print in APA?

    Choose one answer.

    Show the answer: Question 11 of 18

    Answer: (Iyer & Østergaard, 2024; Rao, 2021)

    Write citations next to each other with a space, and the style decides how to join them.

  12. Question 12 of 18 A key from a manager is my/key-2020. How do you cite it in Typst?

    Choose one answer.

    Show the answer: Question 12 of 18

    Answer: #cite(label("my/key-2020"))

    label("…") turns any string into a label, which is the way to cite keys that a label's syntax does not allow.

  13. Question 13 of 18 Which rule does Typst apply first when it decides which list takes a citation?

    Choose one answer.

    Show the answer: Question 13 of 18

    Answer: A list whose target selects the citation

    Targets give explicit control; without them, the nearest list that holds the key takes the citation.

  14. Question 14 of 18 In datasets.typ, the box's list came before Works cited. Why were the first citations of the text numbered [3] and [4]?

    Choose one answer.

    Show the answer: Question 14 of 18

    Answer: Lists of one group share a numbering in the order they are printed, and the box's list printed first

    Give a side list group: none, or place the lists in the order a reader meets them, to keep numbers readable.

  15. Question 15 of 18 A Typst report needs a list at the end of each chapter, each numbered from [1]. What setup gives that?

    Choose one answer.

    Show the answer: Question 15 of 18

    Answer: A bibliography after each chapter, and #set bibliography(group: none)

    The default rules already give each chapter its own list when a list follows each chapter; the group decides the numbering.

  16. Question 16 of 18 How did the day of the web page's access date differ between biblatex's IEEE style and Typst's?

    Choose one answer.

    Show the answer: Question 16 of 18

    Answer: Typst wrote the day with a leading zero; biblatex wrote it without one

    Small differences like this come from the styles, not the data; read the list in the style your venue uses.

  17. Question 17 of 18 Your Typst paper must have a heading References, like the biblatex version. What do you change?

    Choose one answer.

    Show the answer: Question 17 of 18

    Answer: Set title: [References] on the bibliography

    The heading is the bibliography's title parameter, separate from the style.

  18. Question 18 of 18 One .bib file must serve a biblatex paper in IEEE style and a Typst report in Chicago author-date. How do you store titles?

    Choose one answer.

    Show the answer: Question 18 of 18

    Answer: In sentence case, with proper nouns and acronyms braced

    The CSL specification prefers sentence case because title case can be made from it; braces keep proper nouns right in both programs.

Interview questions

Warm-up (fresher to 2–5 years): Typst reads both .bib and Hayagriva files. When would you write Hayagriva?

Both give the same output: in this lesson, the text of two PDFs built from refs.yml and from refs.bib was identical. The choice is about the data. Hayagriva is YAML designed for Typst: a journal or a book is a nested parent entry with its own fields, each person is one string in a list, so no and can split an organisation’s name, and dates are ISO dates. That makes it easy to write and read by hand or from a script. A .bib file is what BibTeX, Biber and reference managers such as Zotero read and write, so it is the right choice whenever the same data also feeds a LaTeX document or comes from a manager. Write Hayagriva for a project only Typst will ever read, and keep .bib otherwise.

Two harder questions follow: a journal’s CSL file whose output does not match its guide, and moving a paper’s bibliography from biblatex to Typst. Plan your first step before you open each one:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Mid to senior

    A journal sends its CSL file for your Typst paper. The rendered list follows the journal's guide except in three ways: article titles appear in title case where the guide wants sentence case, a dataset is labelled as software, and one name is printed wrongly. Find each cause and fix it without editing the journal's style.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    A lab moves its reports from LaTeX with biblatex's IEEE style to Typst, keeping the same .bib file of 400 entries. The first Typst build differs from the old PDFs in titles, dates and headings. Plan the move so that the reports still meet the IEEE guide, and say how you prove it.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • @key cites and #bibliography loads and prints in one compile; a key that no list holds, or a citation in a document without a list, stops the compile.
  • Hayagriva is Typst’s YAML format, with nested parents and one string per person; it prints what the same .bib data prints, and a .bib file stays the choice when LaTeX or a manager shares the data.
  • style takes a built-in name or a CSL file’s path, so a journal’s CSL style works by path, and sys.inputs lets the command line choose it; renamed styles warn and unknown ones stop.
  • form gives prose, author, year, full or no citation, and @key[…] a page, with the style deciding how each looks.
  • Several bibliographies take citations by target, then the nearest list with the key, and a group shares one numbering in print order; group: none restarts it.
  • Typst’s CSL styles print titles as stored and only turn them into title case, so store titles in sentence case with braced proper nouns for a file that biblatex and Typst share, and proof-read each style’s list.

Flashcards · 8 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. How does Typst cite and print a bibliography?

    @key cites, and #bibliography("refs.bib") loads the data and prints the list where it stands, in one compile with no other program. The default style is IEEE.

  2. What does Typst do with a key that no bibliography holds?

    It stops the compile: label does not exist in the document. A citation in a document with no bibliography at all stops it too.

  3. How do you list an entry in Typst without citing it in the text?

    #cite(<key>, form: none) for one entry, or #bibliography("refs.bib", full: true) for every entry of the file.

  4. What is Hayagriva, and when do you choose it?

    Typst's YAML bibliography format, with journals and books as nested parents and one string per person. Choose it for data only Typst reads; keep a .bib file when LaTeX or a reference manager shares it.

  5. How do you use a journal's own CSL style in Typst?

    Save the .csl file next to the document and give its path as the style parameter of #bibliography; built-in styles are named, such as "apa" or "ieee".

  6. What does #cite(<key>, form: "prose") print?

    A citation woven into the sentence, such as Śarmā & Okafor (2023) in APA, like biblatex's \textcite; @key[p. 45] adds a page to an ordinary citation.

  7. How do several Typst bibliographies share or restart their numbers?

    Lists of the default group share one numbering, in the order they are printed; #set bibliography(group: none) makes each list start at [1].

  8. Why store .bib titles in sentence case for Typst?

    CSL styles print a title as stored and only ever convert it to title case, because a program cannot find the proper nouns to lower the rest. Brace the proper nouns as well.

Terms in this lesson

CSL
Citation Style Language: an XML format for citation styles. A CSL file describes how citations and the reference list look, and Typst, Zotero and other programs read it.
Hayagriva
Typst's own bibliography format, a YAML file in which each entry has a type, a person is one string and a journal or book is a nested parent entry.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.