Tutorial: your first manuscript in 15 minutes
This tutorial walks one path. By the end you will have a Quarto
manuscript with citations resolved automatically from DOIs and PubMed
IDs, rendering itself on every push, deployed to GitHub Pages with a
/v/<commit-sha>/ immutable permalink for each commit.
Budget: 15 minutes if you have Quarto, uv, and gh already on your
machine. First render takes longer because Quarto installs TinyTeX the
first time it sees a PDF format. After that, every render is fast.
You will not learn why the design choices are this way — that’s the Design and Citation pipeline pages’ job. This tutorial is doing, not understanding.
To set the example: the tooling that makes a Quarto manuscript
self-rendering, citation-resolving, and version-banner-aware draws on
the broader Quarto + pandoc-citeproc ecosystem; for the data side of a
typical manuscript, the tidyverse (Wickham et al. 2019) is the
most-cited starting point in R, single-cell methods like Seurat (Stuart
et al. 2018) anchor a lot of methods-paper bibliographies, and
transformer architectures (Vaswani et al. 2023) for LLM-driven analysis
tooling, and reference datasets (2013) anchor the biological claims a
paper makes. Those four citations live in this paragraph, were resolved
by quartobot resolve against their registrars (Crossref, bioRxiv via
Crossref, PubMed), and pandoc-citeproc formatted the inline citations
and bibliography section below.
Before you start
Section titled “Before you start”You need:
- Quarto ≥ 1.4 —
quarto --version. Install Quarto if needed. uv—uv --version. Install uv if needed; it handles the Python install for you transparently.gh(the GitHub CLI) —gh --version. Install gh if needed.- A GitHub account authenticated with
gh auth login.
That’s it. No separate Python install, no quarto add step, no Quarto
extension to install — uv tool install quartobot brings everything
along, including the resolver library.
1. Install quartobot
Section titled “1. Install quartobot”uv tool install quartobotThis puts quartobot on your user PATH so Quarto’s pre-render
subprocess can find it without venv activation. Confirm:
quartobot --versionquartobot, version 0.3.0You should see quartobot, version 0.2.0 or later.
2. Create the project
Section titled “2. Create the project”Use Quarto’s own scaffolder for the project shape:
quarto create project manuscript my-papercd my-paperQuarto writes a manuscript-shaped directory: an index.qmd, a
_quarto.yml, and the layout pandoc expects for a single-document
manuscript.
3. Wire in citation resolution
Section titled “3. Wire in citation resolution”Layer the citation pipeline on top:
quartobot initinit adds two new files and modifies .gitignore: a seed
references.bib you can hand-curate any non-registrar references into,
plus .gitignore lines for _book/, _freeze/, .quarto/,
*_files/, **/*.quarto_ipynb, and references.json. Because
quarto create project already wrote a _quarto.yml, init won’t
touch it; instead it prints a YAML snippet to paste in yourself. Copy
the snippet and merge it into your _quarto.yml under the existing
project: block — it adds the pre-render: line plus a bibliography:
list with both references.bib and references.json.
That’s the minimum. If all you want is citations resolved from @doi:
and friends, stop here.
4. Write a paragraph with real citations
Section titled “4. Write a paragraph with real citations”Open index.qmd and replace the body with a paragraph that uses the
cite keys quartobot supports. Authors who write the prose below get the
rendered references below it for free — no hand-curating a .bib per
source.
The tooling stack for a modern computational manuscript spansseveral sources. The tidyverse [@doi:10.21105/joss.01686] gives Rusers a coherent grammar for data manipulation. Single-cellintegration approaches like Seurat [@doi:10.1101/460147], still onbioRxiv as a preprint, sit alongside transformer architectures[@arxiv:1706.03762] for the LLM-driven tooling now common inanalysis pipelines. Reference datasets like the Genotype-TissueExpression Consortium's pilot analysis [@pmid:23715323] anchor thebiological claims.Four cite keys, four registrars (Crossref, bioRxiv via Crossref, arXiv, PubMed). Save the file.
5. See what quartobot scan reports
Section titled “5. See what quartobot scan reports”Before rendering, ask quartobot what citations it sees. The same prose
you just wrote, scanned by quartobot scan:
quartobot scan fixtures/sample-paper/arxiv: 1706.03762doi: 10.1101/460147 10.21105/joss.01686pmid: 23715323
4 unique key(s), 4 total occurrence(s) across 1 file(s).That’s the inventory the pre-render hook will resolve when
quarto render runs. Each prefix groups its keys; the summary line
reports the total.
6. Render locally
Section titled “6. Render locally”quarto renderFirst render installs TinyTeX (Quarto handles this; takes 1–2 minutes). On the second render and after, it’s seconds.
The pre-render hook fires before pandoc runs. It:
- Scans
index.qmdfor cite keys. - Calls each registrar (Crossref for the DOI, PubMed for the PMID, arXiv for the arXiv preprint) to resolve canonical metadata.
- Writes the resulting CSL JSON to
references.json. - Hands control back to pandoc, which reads
references.jsonand formats the citations.
Open _output/index.html (or index.pdf). The citations show as
formatted references with author names, journal, year. No empty [?]
placeholders.
Re-run quarto render. Now it’s near-instant — the pre-render hook sees
references.json already exists with all keys cached, skips the network
round-trip, and pandoc renders straight through.
7. Add the publish-on-every-commit CI
Section titled “7. Add the publish-on-every-commit CI”If you want every push to your GitHub repo to render the manuscript,
deploy it to GitHub Pages, embed a “this version: <sha>” banner in the
rendered HTML, and post a sticky preview comment on each PR — add the
second layer:
quartobot use github-ciThis scaffolds .github/workflows/render.yml (the trigger), the
PR-preview cleanup workflow, the version-banner Quarto include, and
prints a YAML snippet to merge into your _quarto.yml so the banner
appears in the rendered HTML.
Skip this step entirely if you already have CI you’re happy with, or if
you plan to publish via quarto publish. The citation pipeline from
step 3 works the same either way.
For the full set of inputs you can override on the scaffolded workflow (formats, manuscript-name, quarto-version, project-title, etc.), see Workflows and actions in the Reference section. Same page covers the composite actions if you’d rather compose your own workflow instead.
Add the snippet that quartobot use github-ci printed to your
_quarto.yml. It will look roughly like:
format: html: include-before-body: - _version-banner.html8. Push to GitHub
Section titled “8. Push to GitHub”gh repo create my-paper --source=. --public --pushgh creates the repo, pushes your commit, and gives you the URL.
The render workflow fires on push. Watch it land:
gh run watchWhen the workflow finishes, GitHub Pages serves your manuscript at
https://<your-handle>.github.io/my-paper/. Every commit also deploys
to a versioned subdirectory:
https://<your-handle>.github.io/my-paper/v/<sha>/index.html. The
version banner in the rendered HTML links you between them.
9. Open a pull request
Section titled “9. Open a pull request”Make a change. Push to a branch. Open a PR.
git checkout -b add-context# edit index.qmd, add another sentence with another citationgit add index.qmdgit commit -m "Add context paragraph"git push -u origin add-contextgh pr create --fillWithin a couple of minutes a sticky comment lands on the PR with a link to a preview render. Reviewers see exactly what your branch renders to without checking it out locally.
When you merge the PR, quartobot use github-ci’s cleanup workflow
removes the preview directory from gh-pages; the merge commit gets its
own /v/<sha>/ permalink alongside the latest.
You now have
Section titled “You now have”- A manuscript that builds itself on every push.
- Citations resolved from registrars at render time, cached so CI never sees a network blip mid-render.
- An immutable
/v/<sha>/URL for every commit anyone can cite. - PR previews via sticky comment.
- A version banner in the rendered HTML pointing at “this version” and “the latest version” of the paper.
Where to next
Section titled “Where to next”- CLI reference — every command, every flag.
- MCP server — point Claude Desktop, Codex, or Gemini Code
Assist at
quartobot mcpso an agent can call theresolve_citationtool while you draft. - Migrating from manubot — if you have a manubot manuscript and want to translate the layout.
- Design — the architecture decisions and prior art.
References
Section titled “References”2013. “The Genotype-Tissue Expression (GTEx) Project.” Nature Genetics 45 (6): 580–85. https://doi.org/10.1038/ng.2653.
Stuart, Tim, Andrew Butler, Paul Hoffman, et al. 2018. “Comprehensive Integration of Single Cell Data.” openRxiv, November 2. https://doi.org/10.1101/460147.
Vaswani, Ashish, Noam Shazeer, Niki Parmar, et al. 2023. “Attention Is All You Need.” In arXiv, 1706.03762. arXiv. https://arxiv.org/abs/1706.03762.
Wickham, Hadley, Mara Averick, Jennifer Bryan, et al. 2019. “Welcome to the Tidyverse.” Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.