ts-syntax-highlighter
A performant and minimal syntax highlighter for TypeScript, JavaScript, HTML, CSS, and STX. Inspired by Shiki and Torchlight, built with extensibility in mind.
Features
Core Features
- 🚀 Performant - Fast tokenization with built-in caching
- 🎨 Beautiful Themes - GitHub Dark, GitHub Light, and Nord themes included
- 🔧 Extensible - Plugin system for custom languages, themes, and transformers
- 📦 Zero Dependencies - Minimal footprint, built for Bun
- 🎯 Type-Safe - Full TypeScript support
- 🌐 Multiple Languages - JavaScript, TypeScript, HTML, CSS, and STX support
- 💻 CLI & Library - Use as a library or command-line tool
Advanced Features (Competitive with Shiki & Torchlight)
- 🎯 Focus Mode - Dim non-important lines (Torchlight-style)
- 📝 Code Annotations - Add contextual notes to specific lines
- ➕ Diff Highlighting - Show added/removed lines with indicators
- 🌓 Dual Theme Support - Automatic light/dark mode switching
- 🔒 Privacy/Blur - Blur sensitive data (API keys, credentials)
- 🖥️ ANSI Output - Colored terminal output for CLI tools
- 📋 Copy Button - Built-in copy-to-clipboard support
- 🔄 Token Transformers - Modify individual tokens (blur, highlight, emphasize)
Installation
bun add ts-syntax-highlighter
Why Choose ts-syntax-highlighter?
Compared to Shiki and Torchlight:
- ✅ Smaller Bundle - 50KB vs Shiki's 6MB
- ✅ More Features - Focus mode, annotations, ANSI output, blur/privacy
- ✅ True Offline - No API calls required (unlike Torchlight)
- ✅ Built-in Caching - Faster repeated highlighting
- ✅ Dual Themes - Light/dark mode out of the box
- ✅ Full Control - No vendor lock-in, 100% customizable
See FEATURES.md for detailed comparison.
Quick Start
As a Library
import { createHighlighter } from 'ts-syntax-highlighter'
const highlighter = await createHighlighter({
theme: 'github-dark',
cache: true,
})
const result = await highlighter.highlight(
'const greeting = "Hello World";',
'javascript',
{
lineNumbers: true,
}
)
console.log(result.html)
console.log(result.css)
Quick Highlight Function
import { highlight } from 'ts-syntax-highlighter'
const result = await highlight(
'function add(a: number, b: number) { return a + b; }',
'typescript'
)
As a CLI
syntax highlight code.ts typescript --theme github-dark --output highlighted.html
syntax highlight app.js javascript --line-numbers
syntax languages
syntax themes
syntax info typescript
syntax theme-info nord
Configuration
Create a syntax.config.ts file in your project root:
import type { SyntaxHighlighterConfig } from 'ts-syntax-highlighter'
export default {
verbose: false,
theme: 'github-dark',
defaultLanguage: 'javascript',
cache: true,
plugins: [],
} satisfies SyntaxHighlighterConfig
Supported Languages
- JavaScript (js, javascript)
- TypeScript (ts, typescript)
- HTML (html, htm)
- CSS (css)
- STX (stx)
Themes
- GitHub Dark - Dark theme inspired by GitHub
- GitHub Light - Light theme inspired by GitHub
- Nord - Nord color scheme
Advanced Usage
Custom Themes
import type { Theme } from 'ts-syntax-highlighter'
import { createHighlighter } from 'ts-syntax-highlighter'
const customTheme: Theme = {
name: 'My Theme',
type: 'dark',
colors: {
'editor.background': '#1e1e1e',
'editor.foreground': '#d4d4d4',
},
tokenColors: [
{
scope: ['comment'],
settings: {
foreground: '#6A9955',
fontStyle: 'italic',
},
},
],
}
const highlighter = await createHighlighter()
await highlighter.loadTheme(customTheme)
Custom Languages
import type { Language } from 'ts-syntax-highlighter'
const customLanguage: Language = {
id: 'mylang',
name: 'My Language',
aliases: ['ml'],
extensions: ['.ml'],
grammar: {
name: 'My Language',
scopeName: 'source.mylang',
patterns: [
{
name: 'keyword.mylang',
match: '\\b(if|else|while)\\b',
},
],
},
}
const highlighter = await createHighlighter()
await highlighter.loadLanguage(customLanguage)
Plugins
Create custom plugins to extend functionality:
import type { TokenLine } from 'ts-syntax-highlighter'
import { createHighlighter, createTransformerPlugin } from 'ts-syntax-highlighter'
const myPlugin = createTransformerPlugin('my-plugin', {
name: 'my-transformer',
transform: (tokens: TokenLine[]) => {
return tokens
},
})
const highlighter = await createHighlighter({
plugins: [myPlugin],
})
Diff Highlighting
const result = await highlighter.highlight(code, 'javascript', {
lineNumbers: true,
addedLines: [2, 5],
removedLines: [3],
annotations: [
{ line: 2, text: 'Fixed bug', type: 'success' },
],
})
Focus Mode (Torchlight-style)
const result = await highlighter.highlight(code, 'javascript', {
focusLines: [3, 4, 5],
dimLines: [1, 2, 6, 7],
})
Dual Theme Support
import { renderDualTheme } from 'ts-syntax-highlighter'
const result = renderDualTheme(tokens, {
lightTheme: githubLight,
darkTheme: githubDark,
lineNumbers: true,
})
ANSI Terminal Output
const result = await highlighter.highlight(code, 'javascript')
console.log(result.ansi)
Line Highlighting
const result = await highlighter.highlight(code, 'javascript', {
lineNumbers: true,
highlightLines: [1, 3, 5],
})
Inline Code
const result = await highlighter.highlight(code, 'javascript', {
inline: true,
})
API Reference
createHighlighter(config?)
Creates a new highlighter instance.
Parameters:
config - Optional configuration object
Returns: Promise<Highlighter>
highlight(code, lang, options?)
Quick highlight function for simple use cases.
Parameters:
code - The code to highlight
lang - The language identifier
options - Optional render options
Returns: Promise<RenderedCode>
Highlighter Methods
highlight(code, lang, options?) - Highlight code
loadLanguage(language) - Load a custom language
loadTheme(theme) - Load a custom theme
getSupportedLanguages() - Get list of supported languages
getSupportedThemes() - Get list of available themes
clearCache() - Clear the token cache
getCacheSize() - Get current cache size
Performance
The highlighter includes several performance optimizations:
- Caching - Tokenized code is cached to avoid re-parsing
- Lazy Loading - Languages and themes are loaded on demand
- Efficient Tokenization - Optimized regex-based tokenizer
- Minimal Dependencies - Small bundle size
Benchmarks
const highlighter = await createHighlighter({ cache: true })
console.time('First highlight')
await highlighter.highlight(largeCodeFile, 'typescript')
console.timeEnd('First highlight')
console.time('Cached highlight')
await highlighter.highlight(largeCodeFile, 'typescript')
console.timeEnd('Cached highlight')
Examples
Basic Example
import { createHighlighter } from 'ts-syntax-highlighter'
const highlighter = await createHighlighter({
theme: 'github-dark',
})
const code = `
function fibonacci(n: number): number {
if (n <= 1) return n
return fibonacci(n - 1) + fibonacci(n - 2)
}
`
const result = await highlighter.highlight(code, 'typescript', {
lineNumbers: true,
})
STX Template Example
const stxCode = `
@extends('layouts.app')
@section('content')
<div class="container">
@if (user.isAuthenticated)
<h1>Welcome, {{ user.name }}!</h1>
@else
<a href="/login">Please log in</a>
@endif
</div>
@endsection
`
const result = await highlighter.highlight(stxCode, 'stx')
Multiple Themes
const highlighter = await createHighlighter()
const lightResult = await highlighter.highlight(code, 'javascript', {
theme: 'github-light',
})
const darkResult = await highlighter.highlight(code, 'javascript', {
theme: 'github-dark',
})
const nordResult = await highlighter.highlight(code, 'javascript', {
theme: 'nord',
})
Contributing
Contributions are welcome! Please see CONTRIBUTING for details.
License
MIT License - see LICENSE for details.
Acknowledgments
Inspired by:
- Shiki - Beautiful syntax highlighter
- Torchlight - Code highlighting service
- STX - Blade-inspired templating engine