BunPress Documentation
⌘ K

Syntax Highlighting

BunPress provides beautiful code syntax highlighting powered by ts-syntax-highlighter, a blazing-fast, zero-dependency syntax highlighter built specifically for Bun.

Overview

Code blocks in your markdown are automatically highlighted with proper syntax coloring for better readability. The highlighter supports multiple languages and includes features like line highlighting, line numbers, and diff indicators.

Supported Languages

BunPress supports syntax highlighting for the following languages:

  • JavaScript (js, javascript, jsx)
  • TypeScript (ts, typescript, tsx)
  • HTML (html, htm)
  • CSS (css)
  • JSON (json)
  • STX (stx) - Blade-like templating
  • Important

    Shell/Bash commands (bash, sh, shell) are not currently supported for syntax highlighting. Code will be displayed in a monospace font with HTML entities properly escaped for security.

Tip

For shell commands, you can omit the language identifier or use text for plain formatting.

Basic Usage

Simply use standard markdown code fences with a language identifier:

const greeting = 'Hello World'

console.log(greeting)

Result:

const greeting ='Hello World' 'Hello World'
console.log(greeting)

Language Examples

JavaScript

function fibonacci(n) {

if (n <= 1) return n

return fibonacci(n - 1) + fibonacci(n - 2)

}

const result = fibonacci(10)

console.log(result)

TypeScript

interface User {

name: string

age: number

email?: string

}

function greetUser(user: User): string {

return Hello, ${user.name}!

}

const user: User = { name: 'Alice', age: 30 }

console.log(greetUser(user))

HTML

My Page

Welcome

CSS

.container {

display: flex;

flex-direction: column;

gap: 1rem;

padding: 2rem;

background: linear-gradient(to right, #667eea, #764ba2);

}

@media (prefers-color-scheme: dark) {

.container {

background: #1a1a1a;

}

}

JSON

{

"name": "bunpress",

"version": "1.0.0",

"description": "Modern documentation engine",

"dependencies": {

"ts-syntax-highlighter": "^0.1.0"

}

}

Advanced Features

Line Highlighting

Highlight specific lines to draw attention to important code:

function fibonacci(n) {

if (n <= 1) return n // This line is highlighted

let a = 0 // These lines

let b = 1 // are also

let temp // highlighted

for (let i = 2; i <= n; i++) {

temp = a + b

a = b

b = temp

}

return b

}

Note

Use {line-numbers} syntax where line-numbers can be a single number, a range (1-5), or a comma-separated list (1,3,5-7).

Line Numbers

Enable line numbers for easier reference:

function add(a: number, b: number): number {

return a + b

}

function multiply(a: number, b: number): number {

return a * b

}

Inline Code Markers

Use special comments to add visual indicators to your code:

Focus Lines

function example() {

const important = true // [!code focus]

const other = false

return important

}

Tip

Focused lines remain clear while unfocused lines are dimmed.

Diff Highlighting

function greet(name) {

console.log('Hi') // [!code --]

console.log(Hello, ${name}!) // [!code ++]

}

Error and Warning Indicators

function divide(a, b) {

return a / b // [!code error]

// Should check for division by zero!

}

function calculate(x) {

const result = x * 2 // [!code warning]

// Consider using a more descriptive variable name

return result

}

Code in Multiple Languages

Use code groups to show examples in different languages:

npm install bunpress

yarn add bunpress

bun add bunpress

See Code Groups for more details.

Themes

BunPress uses a light theme by default with automatic dark mode support:

The theme switching uses CSS media queries:

@media (prefers-color-scheme: dark) {
  /* Dark theme styles applied here */
}

Note

Custom theme support is planned for future versions.

Performance

The syntax highlighter is designed for speed:

Typical Performance

Code Size Highlight Time
Small (10-20 lines) < 50ms
Medium (50 lines) < 100ms
Large (100+ lines) < 500ms

Styling

The syntax highlighter provides comprehensive CSS classes for customization:

/* Basic code block styling */
pre {
  overflow-x: auto;
  padding: 1rem;
  border-radius: 0.5rem;
}

/* Line highlighting */
.line.highlighted {
  background-color: rgba(255, 255, 0, 0.1);
  border-left: 3px solid #fbbf24;
}

/* Focus mode */
.line.focused {
  filter: none;
}

.line.dimmed {
  opacity: 0.5;
}

/* Diff highlighting */
.line.diff-add {
  background-color: rgba(16, 185, 129, 0.1);
  border-left: 3px solid #10b981;
}

.line.diff-remove {
  background-color: rgba(239, 68, 68, 0.1);
  border-left: 3px solid #ef4444;
}

Comparison with Shiki

BunPress previously used Shiki but switched to ts-syntax-highlighter for several reasons:

Feature ts-syntax-highlighter Shiki
Bundle Size ~50KB ~6MB
Dependencies Zero Many
Performance Async, cached Slower initialization
Bun Native ✅ Yes ❌ No
Grammar Files Built-in External
Language Support 6 core languages 200+ languages

Tip

If you need support for languages beyond the core 6, ts-syntax-highlighter supports custom language definitions.

Troubleshooting

Code not highlighting

If your code isn't being highlighted:

1. Check the language identifier - Make sure you're using a supported language

2. Verify the syntax - Ensure the code fence uses triple backticks

3. Check for typos - Language identifiers are case-insensitive but must be spelled correctly

✅ Correct:

const x = 42


❌ Incorrect:

const x = 42

\`\`\`

<div class="github-alert github-alert-note">
  <p class="github-alert-title">
    <svg class="github-alert-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>
    Note
  </p>
  <div class="github-alert-content">
    <p>Common unsupported languages include: <code>bash</code>, <code>sh</code>, <code>shell</code>, <code>python</code>, <code>ruby</code>, <code>go</code>, <code>rust</code>, <code>java</code>, <code>php</code>, and others. These will display as plain monospace text.</p>
  </div>
</div>

### Styling issues

If the highlighting doesn't look right:

<div class="github-alert github-alert-important">
  <p class="github-alert-title">
    <svg class="github-alert-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>
    Important
  </p>
  <div class="github-alert-content">
    <p>Make sure your custom CSS isn't overriding the syntax highlighting styles.</p>
  </div>
</div>

Check for CSS conflicts in your browser's developer tools.

### Performance issues

For very large code blocks:

<div class="github-alert github-alert-tip">
  <p class="github-alert-title">
    <svg class="github-alert-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"></path></svg>
    Tip
  </p>
  <div class="github-alert-content">
    <p>Consider splitting large code examples into smaller, focused examples.</p>
  </div>
</div>

Smaller code blocks are easier to read and highlight faster.

## Best Practices

### Choose the Right Language

Always specify the language for better highlighting:

✅ Good:

const greeting: string ='Hello' 'Hello'

❌ Avoid:

const greeting = 'Hello'

\\\`

Keep Code Examples Focused

Tip

Show only relevant code. Use comments or line highlighting to guide attention.

// ✅ Good: Focused example
interface User {
  name: string
  age: number
}

// ❌ Avoid: Too much code
// (showing entire file with hundreds of lines)

Use Inline Code for Single Values

For short snippets, use inline code instead of code blocks:

Use the `console.log()` function to debug.
Set `DEBUG=true` in your environment.

Combine with Other Features

Syntax highlighting works great with other BunPress features:

API Reference

For programmatic use, BunPress exports the following functions:

import {
  highlightCode,
  normalizeLanguage,
  isLanguageSupported,
  getSyntaxHighlightingStyles
} from'@stacksjs/bunpress' '@stacksjs/bunpress'

// Highlight code (async)
const html = await highlightCode('const x = 42''const x = 42','javascript' 'javascript')

// Check if language is supported
if (isLanguageSupported('python''python')) {
  // Language is supported
}

// Normalize language alias
const lang = normalizeLanguage('js''js')// Returns 'javascript' // Returns 'javascript'

// Get CSS styles
const styles = getSyntaxHighlightingStyles()

Note

These functions are primarily for advanced usage and plugin development. Most users won't need to use them directly.

Working with Shell Commands

Since bash/sh is not currently supported, here are some alternatives for displaying shell commands:

Option 1: Use Plain Text

Omit the language identifier or use text:

npm install bunpress

bun add bunpress

Option 2: Use Code Groups

For package manager commands, use code groups without highlighting:

<div class="code-group" id="code-group-1p7wi11us">
  <div class="code-group-tabs">
    <button class="code-group-tab active" onclick="switchCodeTab('code-group-1p7wi11us', 0)">npm</button><button class="code-group-tab " onclick="switchCodeTab('code-group-1p7wi11us', 1)">yarn</button><button class="code-group-tab " onclick="switchCodeTab('code-group-1p7wi11us', 2)">bun</button>
  </div>
  <div class="code-group-panels">
    <div class="code-group-panel active" data-panel="0">
  <pre data-lang="text"><code class="language-text"><span class="line">npm install bunpress</span>
<span class="line"></span></code></pre>
</div>
<div class="code-group-panel " data-panel="1">
  <pre data-lang="text"><code class="language-text"><span class="line">yarn add bunpress</span>
<span class="line"></span></code></pre>
</div>
<div class="code-group-panel " data-panel="2">
  <pre data-lang="text"><code class="language-text"><span class="line">bun add bunpress</span>
<span class="line"></span></code></pre>
</div>
  </div>
</div>

Option 3: Inline Code

For short commands, use inline code:

Run `npm install bunpress` to install.
Use `bun dev` to start the development server.

Note

Shell/Bash highlighting support is planned for a future release through custom language definitions.

Future Enhancements

Planned improvements for syntax highlighting:

See Also