Skip to content
Taliesin User Guide

2 Choosing Taliesin

What adopting Taliesin costs and what it is good at: how much of your source is portable, what the speed numbers are in absolute terms, and what happens if you leave.

Every other chapter tells you how to use the tool. This one helps you decide whether to adopt it: what you are committing to, what you get, and what leaving costs.

2.1 Source portability

The first worry about a single-author tool is lock-in: that a year of writing ends up in a dialect only this program understands.

Taliesin’s own corpus is 80 .tmd documents and 7,099 lines of real writing, the largest sample that exists. Of those lines, 453 (6.4%) carry any construct beyond plain CommonMark. The other 93.6% is Markdown, and any Markdown tool reads it.

ConstructLinesShare
Executable fence (```{python})1031.5%
Attribute block ({#sec-id}, {.unnumbered})961.4%
Citation / cross-reference ([@key], @fig-x)901.3%
Fenced div (::: {.callout-note})761.1%
Cell option (#| label: fig-x)660.9%
Shortcode ({{< include … >}})220.3%

(Measured 2026-09-25 over corpus/**/*.tmd; a line using two constructs is counted once in the total and once per family, so the family rows sum to more than the total. Reproduce it with python3 tools/portability-census.py, which is where these numbers come from and which spells out each family’s definition. The script is committed because this table was first published in July as “measured rather than asserted” while the script that measured it was not, and by August its document and line counts no longer reproduced.)

None of those six constructs originated in Taliesin. Each is Pandoc or Quarto vocabulary that predates it, so the 6.4% is syntax another Pandoc-family tool already parses. .tmd is a file extension, not a format. A project arriving from Quarto likewise brings its sentences, fenced cells, #| options, ::: divs, math, citations and cross-references across unchanged. Taliesin reads only .tmd pages and does not read _quarto.yml, so rename each .qmd to .tmd and add a _site.yml (see the configuration reference). Then taliesin build . --check-only names the short list of vocabulary that differs, with a file and a line for each.

The check cannot flag an unknown cross-reference prefix. Only @fig-, @tbl-, @sec-, @eq- and @lst- are references here; anything else (@thm-, @def-) stays literal text, because @rust-lang in a sentence is indistinguishable from a typo. Grep your source for those prefixes before you migrate.

2.2 Speed measurements

Speed is the reason this tool exists. These are absolute numbers on one machine, and they measure Taliesin’s work only. A batch document compiler doing a cold Pandoc pass with execution is doing different work, so a ratio between its times and these would be misleading.

MeasurementValueWhat it covers
Whole-project build, docs/internals (6 pages)0.16 sParse, render, highlight, math, search index, assets
Whole-project build, this guide (16 pages)0.21 sIncluding executed cells replayed from _freeze/
Whole-project build, corpus/tech-blog (17 pages)0.35 s20.7 ms/page, the heaviest project in the tree
preview time-to-ready, single document≈40 msProcess spawn to the first HTTP 200; ≈0.3 s for a highlight-dense document
preview time-to-ready, 16-page book≈110 msDiscovery, nav, cross-reference registry, first render
Warm edit: diff only0.45 msThe block diff for one keystroke-sized edit
Warm edit: re-render + diff2.9 msOne document, against a 107 ms cold render of it
Warm-edit payload3.2 KBVersus a 288 KB full page a reload would refetch
Save to the open tab, corpus/tech-blog (17 pages)≈35 msEnd to end: the watcher, the cross-reference refresh, re-render, diff, websocket
Cross-reference refresh, this guide (16 pages)3.0 msAdded to every save in a site preview

(Every figure re-measured 2026-09-24, the 16-page time-to-ready 2026-09-25, release build, on a 16-core machine with no other build running. Each build figure is the duration the build prints for itself, best of three with a warm _freeze/ cache, and each page count is the one it reports (find … -name '*.html' is not the page count, since a project may ship its own 404.html and _-prefixed files are never pages). The ready rows are the median of five runs: wall time from spawning taliesin preview <target> <port> to the first HTTP 200 from its socket, polled every 2 ms, for a small document (corpus/native-tmd.tmd); the ≈0.3 s companion figure is corpus/highlight.tmd, written to be highlight-dense. The warm-edit and cross-reference rows come from tools/live-edit-bench, run as cargo run --release -p live-edit-bench; its committed RESULTS.md labels them indicative (the numbers vary by machine). The structural rows it also records, the op counts and payload bytes, are deterministic and gated by a regression test. The save row is measured by crates/server/tests/save_to_open_tab.rs, run as cargo test --release -p taliesin-server --test save_to_open_tab -- --nocapture: from writing the same post the warm-edit rows measure to its open tab receiving the change, median of nine saves in place and nine renamed over the old file, 35 to 44 ms over three runs. The watcher’s wait for a save’s events to stop, 15 ms of quiet, is inside it.)

Because the warm edit is a diff, its cost tracks what you changed rather than how large the document is. See the block model for the operation breakdown behind that payload figure.

The last row is an exception to that scaling. In a multi-page project a save also re-derives the cross-reference registry before the diff, and its harvest renders every page, without typesetting math or highlighting code, to recover the cross-page figure and equation numbers. That pass scales with the size of the project while the diff scales with the size of the edit, so it is still O(pages) on every save: 3.0 ms in this guide, and 24 ms for the synthetic 500-page book in tools/live-edit-bench (55 ms when the save moves an anchor, which also rebuilds the search index). Those figures are wall clock across every core the machine offers, so a two-core laptop pays more.

2.3 What Taliesin claims, and who asked for it

Each of these is a thing users of comparable tools have asked for in public. They are listed with their sources so you can check that the need is real and was not retrofitted.

  • Edit in your own editor, see output alongside. (marimo #3114) The .tmd file is the only editing surface and the browser is a read-only view. Click-to-source, the only path from the page back to the editor, never writes to your source.
  • A format a human can read and git diff. (marimo #1379) .tmd is Markdown. See the table above for exactly how much of it is not.
  • Reload on disk change, without losing state. (marimo #2675) A save re-renders and patches in place; scroll position and live canvases survive.
  • Stop restarting the kernel. (Quarto #4201) The kernel is warm for the life of the server, so an edit costs one cell, not one boot.
  • Re-render only what changed; freeze a single cell. (Quarto #3674, #10429) Both are the same mechanism here: a per-cell cumulative content hash.

Cached-output systems in this space carry a standing complaint that the cache can serve a stale result: an output produced by code that has since changed. Taliesin’s cache key is the cumulative hash of a cell’s own code plus every upstream cell in its language plus the interpreter’s identity, so editing anything upstream invalidates that cell and everything downstream. For the axes the key can see (cell code, its upstream, the interpreter), a stale hit cannot happen, and no comparable tool makes that claim. By design, the key does not cover what a cell reads: a data file, an environment variable, a fetched URL, the clock, a library upgraded in place. Mark such a cell #| cache: false and it re-runs every time, along with everything downstream. See Executable content and the cache notes in Troubleshooting.

2.4 Continuity: what you are relying on

Taliesin has one maintainer, and the scope is closed. Version 1.0 does not change that: it means the feature set is final for this tool’s one use case, not that a team stands behind it. In practice there is no support contract or release cadence you can plan around, and nobody but the maintainer knows the codebase. The project continues only while the maintainer works on it.

What you keep if the maintainer stops:

  • Your source is Markdown, 93.6% of it plain CommonMark, all of it in your repository.
  • Pages you already built keep working: they are static HTML with no runtime dependency on the tool that made them.
  • The code is AGPL-3.0, so a fork is always available to anyone who wants one.

So the realistic downside is migrating to another Pandoc-family tool and redoing a small fraction of the syntax, with your writing intact. The table in Source portability bounds that fraction.

The project offers no guarantee of continuity. Its mitigation is that everything the author writes goes through this tool. Both books of this manual, the public website and the regression corpus are .tmd rendered by Taliesin: 112 tracked .tmd files, 12,904 lines, of which the 81-document corpus is re-rendered by every cargo test run. A defect that breaks a page breaks the documentation for that page in the same commit.