This project includes a lightweight, framework-agnostic incremental renderer for Shiki:
src/utils/shiki-render.ts– render<pre><code>HTML with each line wrapped in.linesrc/utils/incremental-tokens.ts– token-based incremental updater (no HTML parsing)
Basic usage (token-based):
import { createHighlighter } from 'shiki'
import { createTokenIncrementalUpdater } from './src/utils/incremental-tokens'
const highlighter = await createHighlighter({ themes: ['vitesse-dark'], langs: ['typescript'] })
const container = document.getElementById('code')!
const updater = createTokenIncrementalUpdater(container, highlighter, {
lang: 'typescript',
theme: 'vitesse-dark',
})
// Stream in more source text over time
updater.update('const a = 1')
updater.update('const a = 12')Note: For non-blocking behavior when many code blocks update concurrently, use createScheduledTokenIncrementalUpdater which defers DOM/token updates to idle time and prioritizes visible containers. The high-level createShikiStreamRenderer also uses the scheduled updater by default to avoid blocking the main thread.
It incrementally updates the last changed line and appends new lines; if earlier lines diverge (e.g. multi-line tokens), it safely falls back to a full re-render.
This project is built with the help of these awesome libraries:
- shiki — Syntax highlighter powered by TextMate grammars and VS Code themes
Thanks to the authors and contributors of these projects!