syntax styling utilities and components for TypeScript, Svelte, Markdown, and more 🎨
fuz_code is a runtime syntax highlighter: it turns source code into HTML with
.token_* CSS classes, and knows nothing about the DOM. It originated as a fork
of Prism (prismjs.com),
but the tokenizer is now a full rewrite — one hand-written single-pass lexer per
language emitting a flat token event stream, without regular expressions.
Highlights:
- a minimal, explicit API to generate stylized HTML —
stylize(code, lang) - stateless ES modules, instead of globals with side effects
- written in TypeScript, with no runtime dependencies
- nine built-in languages (see below), extensible by writing a lexer
Two optional integrations:
- builtin 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 smaller and about two orders of magnitude faster for runtime usage: it runs hand-written single-pass lexers rather than the Oniguruma regexp engine that TextMate grammars require, and has no runtime dependencies instead of 38. Shiki targets build-time use and supports far more languages and themes — pick the tool that fits; fuz_code is optimized for small, fast runtime highlighting.
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 highlighting
const html = syntax_styler_global.stylize(code, 'ts');
// Get the raw flat token event stream for custom processing
const lexed = syntax_styler_global.lex(code, 'ts');Themes are just CSS files, so they work with any JS framework.
With SvelteKit:
// +layout.svelte
import '@fuzdev/fuz_code/theme.css';The primary themes (currently just one) depend 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.js - pre-configured instance with all built-in languages
- @fuzdev/fuz_code/syntax_styler.js - 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 highlighting with HTML generation
See src/lib for the full set of modules.
Registered by default in syntax_styler_global — one hand-written lexer each:
markup(html,mathml,svg)xml(ssml,atom,rss)sveltemd(markdown)ts(TypeScript — also servesjs/javascript, a syntactic subset)cssjson(with comments — jsonc)sh(POSIX/bash family — also servesbash/shell)rust(also servesrs)
Add a language by writing a SyntaxLang lexer and registering it with
add_lang — see the existing lexer_*.ts modules.
Docs are a work in progress:
- this readme has basic usage instructions
- CLAUDE.md has more high-level docs including benchmarks
- code.fuz.dev has usage examples with the Svelte component
- samples on the website (also see the sample files)
- 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/highlight_manager.js -
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. The tokenizer has since been rewritten as
hand-written lexers, but the fork's lineage remains.