Skip to content Skip to table of contents

Taliesin

A Rust dev server that renders Markdown with executable code cells to HTML and patches the open preview block by block. This site is built with it.

GitHub User guide

Taliesin turns .tmd files into static HTML. A .tmd file is Markdown with Python cells that run at build time and JavaScript cells that run in the browser, written in the same syntax Quarto uses.

Until July 2026 I wrote this blog in Quarto. Quarto chains other programs together. Pandoc parses the Markdown, a Jupyter kernel runs the code, and a Deno layer drives both, each started as a fresh process on every render. Taliesin’s first commit is a problem statement about editing posts with live demos in Quarto.

The edit loop

In QuartoCauseIn Taliesin
No way to click a rendered paragraph and land on its source linePandoc drops source positions when it builds its syntax treeEvery block keeps its source position, and Ctrl-click in the preview opens that line in VS Code
Every save reloads the whole previewThe output is a new page each timeA save swaps only the blocks that changed; scroll position and running demos stay as they were
Each render waits for programs to startDeno, Pandoc and a kernel start on every renderOne server and one kernel stay running, and a save re-runs code from the first changed cell onward

On a post with a three.js scene halfway down, fixing a typo above the scene in Quarto reloaded the page, lost my place and restarted the scene. Taliesin sends the same fix as a patch to one paragraph and never touches the scene.

How a save reaches the browser

The server is written in Rust. It parses each file with comrak, a CommonMark parser that reports the source position of every node, and gives each top-level block an id tied to that position.

When a file changes on disk, the server parses it again and runs the code cells on the warm kernel, starting from the first cell whose code changed. Each result is cached under a hash of the cell’s code, every cell above it in the same language, and the interpreter, so an edit upstream invalidates everything below it. The new block list is then diffed against the previous one, and only the changed blocks go over a websocket. The browser swaps those blocks in place and leaves the rest of the page alone.

Speed was the reason to build Taliesin. The guide measures each part of this loop on a 16-core machine.

MeasurementResult
Build a 17-page snapshot of this blog0.35 s
Start taliesin preview on one documentabout 40 ms
Re-render and diff after a small edit2.9 ms
From saving the file to the change showing in the open tababout 35 ms
Data sent for a small edit3.2 KB, against 288 KB for the full page

The portability table I published in July had no committed script behind it, and a month later its counts no longer reproduced. Since then, each number in the guide names the script, benchmark or test that produced it.

Cutting it down

The first plan scoped the project to my own documents, about 30 of them at the start, rather than to Quarto’s feature set. Over the summer it grew a slide-deck engine, a VS Code companion extension and many Quarto options.

In August, before the 1.0 release, I removed roughly 40% of the codebase. The cuts included the slide engine, parts of the companion, and options and lints that none of my documents used. HTML is the only output, and PDF, LaTeX and Word export are permanently out of scope.

Taliesin 1.0 came out on 20 August 2026, and 1.0.1 is the current release, with prebuilt binaries for Linux and macOS. Bug reports are welcome. I do not take feature requests, and the AGPL-3.0 licence lets anyone who wants a feature fork the tool and add it.