Renderers
Every renderer takes the same inputs — source plus the token array from highlighter.highlight().
Browser — CSS Custom Highlights
Highlights the element's text natively via CSS.highlights — no <span> elements are injected. Requires a theme stylesheet that targets the sh-{type} classes (see Themes).
import { highlightElement } from "@opentf/syntax-highlighter"; // One-shot setup for an editable/live element: const handle = await highlightElement(element, source, { language: "javascript", debounceMs: 50, // refresh() coalescing; 0 = synchronous }); handle.refresh(nextSource); // re-highlight new content (debounced) handle.dispose(); // release highlights
Or drive the renderer manually:
import { CSSHighlightRenderer } from "@opentf/syntax-highlighter"; const renderer = new CSSHighlightRenderer(element); renderer.render(source, tokens); renderer.clear(); renderer.dispose();
Page highlighting (Prism-style)
highlightAll finds every <code class="language-*"> (or a language-* class on an ancestor such as the <pre>, as Prism does), loads each language once, and highlights the blocks. You choose how blocks are painted — mode is required:
"highlight"— CSS Custom Highlight API; the DOM is left untouched. Paints nothing where the API is unsupported."html"— replaces each block's content with escaped<span class="sh-*">markup; works in every browser.
import { highlightAll, supportsHighlightAPI } from "@opentf/syntax-highlighter"; import "@opentf/syntax-highlighter/themes/default.css"; const result = await highlightAll({ mode: supportsHighlightAPI() ? "highlight" : "html", // your call root: document, // optional; where to look // selector, defaultLanguage, prefix are optional too }); result.skipped; // blocks with no or an unknown language, left as they were result.dispose(); // release "highlight"-mode ranges (e.g. on navigation)
Unknown languages are skipped rather than thrown, and re-running on the same blocks replaces their highlighting instead of stacking it.
HTML / SSR
Emits escaped HTML with semantic <span class="sh-{type}"> wrappers. Safe for server rendering and static builds — compose your own <pre><code> wrapper as needed.
import { renderHTML } from "@opentf/syntax-highlighter"; const html = renderHTML(source, tokens, { prefix: "sh-", // CSS class prefix for token spans wrapWhitespace: false, // wrap whitespace tokens too });
For build steps and server rendering, highlightCode resolves the language for you and never throws on an unknown one — it returns the escaped code with language: null, so the block still renders as plain text:
import { highlightCode } from "@opentf/syntax-highlighter"; const { html, language } = await highlightCode(code, { language: "tsx" }); const block = `<pre><code class="language-${language ?? "text"}">${html}</code></pre>`;
ANSI terminal
Truecolor output for CLIs and terminals. Themes are plain hex maps converted to ESC[38;2;R;G;Bm; respects NO_COLOR unless color is explicit. Control characters in the source (ESC, BEL, …) are printed in caret notation (^[, ^G) so untrusted input cannot drive the terminal; pass allowControlChars: true for trusted source.
import { renderANSI } from "@opentf/syntax-highlighter"; import { dracula } from "@opentf/syntax-highlighter/ansi/themes/dracula"; const out = renderANSI(source, tokens, { theme: dracula, // hex colors per token type; defaults to defaultTheme color: true, // force on/off; undefined respects NO_COLOR wrapWhitespace: false, allowControlChars: false, // true writes control characters through (trusted source only) }); console.log(out);
JSON / tooling
Serializes the token stream — useful for snapshots, tests, and editor integrations.
import { renderJSON } from "@opentf/syntax-highlighter"; const json = renderJSON(source, tokens);