How do I use cite without a bibliography?

I would like to write my own function for rendering bibliographies, without using the builtin bibliography function. However, I can’t figure out how to use cite without actually including a bibliography. For instance, the following snippet causes an “error: cannot reference text”:

@modelizer-24

[Tural Mammadov, Dietrich Klakow, Alexander Koller, and Andreas Zeller (2025). Learning Program Behavioral Models from Synthesized Input-Output Pairs. ACM Transactions on Software Engineering and Methodology (TOSEM).] <modelizer-24>

Does someone have advice on how to create a bibliography entry to which cite can refer?

1 Like

Hello @akoller,

I am interested in knowing why you would want to rewrite the bibliography, but I suppose you want full control over the layouting.

In which case, you can use custom figures and references. A prototype woud look like this:

  • Define a layout function display-reference that takes in reference data and returns content
  • Define a function reference that passes layouted data to a custom figure
  • You need a show rule for the custom figure (otherwise by default the body is centered for example)
  • You might need a show rule for your figure, but it is optional depending on what you need to do. Usually, writing a numbering function in reference should satisfy your needs.

The output of

@modelizer-24

#reference(
  ("Tural Mammadov", "Dietrich Klakow", "Alexander Koller", "Andreas Zeller"),
  datetime(year: 2025, month: 1, day: 1),
  "Learning Program Behavioral Models from Synthesized Input-Output Pairs",
  "ACM Transactions on Software Engineering and Methodology (TOSEM)",
) <modelizer-24>

would look like

The complete code is below:

Summary
#let display-reference(
  authors,
  date,
  title,
  journal,
) = {
  (
    [[#context counter(figure.where(kind: "reference")).display()]],
    authors.join(", "),
    date.display("[year]"),
    title,
    journal
  ).join(". ")
}
#let reference(
  authors,
  date,
  title,
  journal,
) = figure(
  kind: "reference",
  supplement: none,
  numbering: n => numbering("[1]", n),
  display-reference(
    authors,
    date,
    title,
    journal,
  ),
)
#show figure.where(kind: "reference"): it => {
  set align(left)
  it
}
#show ref: it => {
  let el = it.element
  if el.func() == figure and el.kind == "reference" {
    it
  } else {
    it
  }
}

@modelizer-24

#reference(
  ("Tural Mammadov", "Dietrich Klakow", "Alexander Koller", "Andreas Zeller"),
  datetime(year: 2025, month: 1, day: 1),
  "Learning Program Behavioral Models from Synthesized Input-Output Pairs",
  "ACM Transactions on Software Engineering and Methodology (TOSEM)",
) <modelizer-24>
2 Likes

A quick and hacky way would also be to just do #show bibliography: none. You’d still have to call #bibliography(..) first to make your citations work but with that show-rule, it is no longer displayed in the document nor does it take up any space.

1 Like

For this specific code snippet, the solution would be to use the link function instead:

#link(<modelizer-24>)[[the link]]  // <- this works

Tural Mammadov, Dietrich Klakow, Alexander Koller, and Andreas Zeller (2025). Learning Program Behavioral Models from Synthesized Input-Output Pairs. ACM Transactions on Software Engineering and Methodology (TOSEM).<modelizer-24>
2 Likes

This is a beautiful solution, thank you!

Indeed, I am growing increasingly unhappy with the inflexibility of Typst bibliographies. Sometimes I need fine control over what references are shown in the bibliography, e.g. in the context of a CV; sometimes I want fine control over what elements of a Bibtex entry are shown in the bibliography, without having to dig through a whole CSL file; sometimes I want fine control over how the bib entries are rendered, e.g. boldfacing all entries with a certain Bibtex keyword.

I appreciate that generating bibliographies through CSL allows Typst to tap into a huge library of existing CSL styles, but the CSL that I’ve found for my scientific community is buggy and does not display certain reference types correctly. I’m coming to a point where I don’t see the value in using CSL in the first place, when the rendering of the references can be done so easily with a bit of Typst code.

I already wrote blinky and citegeist to address my issues partially, but I’d like to see if I can just fully circumvent all of CSL - hence my question.

1 Like

I understand your frustration! For the CV usecase, you might want to checkout alexandria.

For the customization, it is indeed more difficult than it “should be”, given that Typst is still an early project.

There are technical reasons (and responsability questions) as to why this is harder than it looks, after all why not just have bibliography.entry like other outline.entry?

The main issue is #942.

In more details:

For bibliography.entry, see PR#5932

As for styling issues such as links (issue #5614), it is blocked because show rules cannot target specific links

As for styling textual elements see this comment in issue #6639, where @laurmaedje points out that CSL provides instructions on appearances (CSS), so Typst directly translate that to text(weight: 300) for example, and not strong, which would be semantically different.

Since bibliography styling is applied directly to text, it’s more difficult for the user to customize.

Hi @quachpas,

yes, I’m aware of all those discussion threads. I’m not blaming Typst or its developers in any way - this is a small team of amazing developers, and they have other things on their plate that are more urgent at a global level. It’s exactly because I want to switch to Typst from Latex in as many contexts as possible that I don’t want to wait for the resolution of these issues.

Furthermore, I just really don’t enjoy working with CSL. I’d much rather just write some Typst code to format the references than learn yet another XML schema.

A preliminary implementation based on your code snippet is here: GitHub - alexanderkoller/bibtypst: Typst remake of Biblatex

I’d be pleased to hear your thoughts on it.

1 Like