Tailmark is a streaming Markdown renderer for React with a proven incremental open-tail pipeline. On the default LF append-only path, both Markdown repair and lexing do O(open tail) work after a safe boundary instead of rescanning the settled document. CI enforces streaming equivalence at every prefix and render-once identity for settled blocks.
On the replayed long-prose, per-token fixture, the final one-run trace kept Tailmark preprocessing effectively flat in a 0.03 to 0.17 ms band while Streamdown 2.5.0 grew linearly from 0.09 to 1.66 ms. The final interleaved comparison also recorded about 20% less cumulative scripting for Tailmark. These are single-run observations from this repository's fixtures and configuration, not stable distributions or universal performance claims. See the full methodology and caveats.
Tailmark was extracted from Traycer's production chat renderer.
bun add @tailmark/react react react-markdownimport { StreamingMarkdown, useCoalescedValue } from "@tailmark/react";
import "@tailmark/react/styles.css";
export function Answer({ content, pending }: { content: string; pending: boolean }) {
const markdown = useCoalescedValue(content);
return (
<StreamingMarkdown isStreaming={pending} reveal caret>
{markdown}
</StreamingMarkdown>
);
}The stylesheet is optional. Without the import, Tailmark renders semantic, data-attributed markup for your own design system.
| Package | Purpose |
|---|---|
@tailmark/core |
React-free repair and incremental block lexing |
@tailmark/react |
React renderer, streaming polish, code chrome, and batching hook |
@tailmark/shiki |
Lazy, dual-theme Shiki integration with an MRU cache |
The public benchmark methodology documents deterministic fixture replay, fairness rules, CI-gated structural counts, real Chrome traces, bundle measurement, raw scope, and known limitations.
Run the deterministic count layer and compare it with the committed CI baseline:
bun run bench:countsReproduce the production browser trace in one command after bun install:
BENCH_RUNS=3 bun run bench:traceThe simple integration example replays a growing response with tables, tasks, TypeScript, rAF coalescing, reveal, caret, and Shiki highlighting.
bun run --cwd examples/streaming-demo devLive demo: tailmark-streaming-demo.vercel.app
The side-by-side race replays the benchmark fixtures through Tailmark and Streamdown 2.5.0 with live React HUDs. Its diagnostic overlay uses identical instrumentation for both lanes, stays off by default, and clearly marks its own measurement overhead.
bun run --cwd examples/bench-race devLive demo: tailmark-bench-race.vercel.app
- Streaming equivalence: every streamed prefix produces the same blocks as a full repair and lex. The adversarial, character-by-character suite lives in
packages/core/test/lexer.test.ts. - Render once: unchanged settled blocks retain their raw references and React Markdown work stays bailed out as the tail grows. The render-count suite lives in
packages/react/test/markdown-block-memo.test.tsx.
MIT. See LICENSE.