syntax styler for TypeScript, Svelte, Markdown, and more 🎨
fuz_code is a syntax styler: it turns source code into HTML with
token CSS classes, or ranges for the
CSS Custom Highlight API.
It originated as a fork of Prism by Lea Verou
and has since been rewritten: each language has a lexer that scans without
regular expressions and emits tokens as a flat stream in a typed array.
The flat token stream is an idea borrowed from pngwn,
the author of Twinkleplop.
Twinkleplop is the broader project: it compiles declarative grammars, covers more languages, and ships themes, annotations, and markdown integrations. fuz_code is narrower, with a lexer written as ordinary code for each of a small set of languages, and a few Svelte components.
Features:
- a minimal, explicit API to generate stylized HTML —
stylize(code, lang) - written in TypeScript; the lexers and styler import nothing outside the package
- built-in languages listed below, extensible by writing a lexer
Two optional integrations:
- Svelte support with a Svelte lexer and a Svelte component
- the default theme integrates with
fuz_css for colors that adapt to the
user's runtime
color-schemepreference — without fuz_css, import theme_variables.css or otherwise define those variables
Compared to Shiki, fuz_code is about two orders of magnitude faster for runtime usage: it runs one single-pass lexer per language rather than the Oniguruma regexp engine that TextMate grammars require. Shiki targets build-time use and supports far more languages and themes.
npm i -D @fuzdev/fuz_code<script lang="ts">
import Code from '@fuzdev/fuz_code/Code.svelte';
</script>
<!-- defaults to Svelte -->
<Code content={svelte_code} />
<!-- select a lang -->
<Code content={ts_code} lang="ts" />import { syntax_styler_global } from '@fuzdev/fuz_code/syntax_styler_global.ts';
// Generate HTML with syntax styling
const html = syntax_styler_global.stylize(code, 'ts');
// Get the flat event stream for custom processing
const lexed = syntax_styler_global.lex(code, 'ts');Themes are CSS files and work with any framework.
With SvelteKit:
// +layout.svelte
import '@fuzdev/fuz_code/theme.css';The default theme depends on fuz_css for color-scheme awareness. See the fuz_css docs for its usage.
If you're not using fuz_css, import theme_variables.css alongside theme.css:
// Without fuz_css:
import '@fuzdev/fuz_code/theme.css';
import '@fuzdev/fuz_code/theme_variables.css';- @fuzdev/fuz_code/syntax_styler_global.ts - pre-configured instance with all built-in languages
- @fuzdev/fuz_code/syntax_styler.ts -
the
SyntaxStylerclass (register your own lexers) - @fuzdev/fuz_code/theme.css - default theme that depends on fuz_css
- @fuzdev/fuz_code/theme_variables.css - CSS variables for non-fuz_css users
- @fuzdev/fuz_code/Code.svelte - Svelte component for syntax styling with HTML generation
- @fuzdev/fuz_code/svelte_preprocess_fuz_code.ts -
build-time preprocessor for static
Codecontent
See src/lib for the full set of modules.
Registered by default in syntax_styler_global:
markup(html,mathml,svg)xml(ssml,atom,rss)sveltemd(markdown)ts(typescript,js,javascript— JS is a syntactic subset)cssjson— accepts comments (JSONC)sh(bash,shell— the POSIX/bash family)rust(rs)
Add a language by writing a SyntaxLang lexer and registering it with
add_lang — see the existing lexer_*.ts modules.
- code.fuz.dev/docs - usage, samples, textarea, benchmark, and API
- CLAUDE.md - architecture and development guidelines
- sample files and tests
Issues and questions are welcome.
For browsers that support the CSS Custom Highlight API, fuz_code provides an experimental component that can use native browser highlighting as an alternative to HTML generation.
Browser support is limited, and the API can't apply layout-affecting styles — bold, italics, font sizes — so themes that use them render differently. The standard Code.svelte component using HTML generation is recommended for most use cases.
<script lang="ts">
import CodeHighlight from '@fuzdev/fuz_code/CodeHighlight.svelte';
</script>
<!-- auto-detect and use CSS Highlight API when available -->
<CodeHighlight content={code} mode="auto" />
<!-- force HTML mode -->
<CodeHighlight content={code} mode="html" />
<!-- force ranges mode (requires browser support) -->
<CodeHighlight content={code} mode="ranges" />When using the experimental highlight component, import the corresponding theme:
// instead of theme.css, import theme_highlight.css in +layout.svelte:
import '@fuzdev/fuz_code/theme_highlight.css';Experimental modules:
- @fuzdev/fuz_code/CodeHighlight.svelte - component supporting both HTML generation and CSS Custom Highlight API
- @fuzdev/fuz_code/CodeTextarea.svelte -
editable
<textarea>with live range highlighting - @fuzdev/fuz_code/highlight_manager.ts -
manages browser
HighlightandRangeAPIs - @fuzdev/fuz_code/theme_highlight.css -
theme with
::highlight()pseudo-elements for CSS Custom Highlight API
License 🐦
Originally forked from Prism
(prismjs.com) by Lea Verou —
with the Svelte support originally based on
prism-svelte by
@pngwn.