BunPress Documentation
⌘ K

Markdown Extensions

BunPress extends standard Markdown with powerful features to enhance your documentation experience.

Custom Containers

BunPress supports custom containers for creating visually distinct content blocks.

Info Container

<div class="custom-block info">
  <p class="custom-block-title">INFO</p>
  <div class="custom-block-content">
    <p>This is an informational note.</p>
  </div>
</div>

INFO

This is an informational note.

Tip Container

<div class="custom-block tip">
  <p class="custom-block-title">TIP</p>
  <div class="custom-block-content">
    <p>This is a helpful tip.</p>
  </div>
</div>

TIP

This is a helpful tip.

Warning Container

<div class="custom-block warning">
  <p class="custom-block-title">WARNING</p>
  <div class="custom-block-content">
    <p>This is a warning message.</p>
  </div>
</div>

WARNING

This is a warning message.

Danger Container

<div class="custom-block danger">
  <p class="custom-block-title">DANGER</p>
  <div class="custom-block-content">
    <p>This indicates dangerous or potentially harmful actions.</p>
  </div>
</div>

DANGER

This indicates dangerous or potentially harmful actions.

Details Container

<details class="custom-block details">
  <summary>Details</summary>
  <div class="custom-block-content">
    <p>This content is hidden by default and can be expanded.</p>
  </div>
</details>
Details

This content is hidden by default and can be expanded.

Emoji Support

BunPress supports emoji shortcodes for easy emoji insertion.

I ❤️ BunPress!

This feature is 🔥!

I ❤️ BunPress!

This feature is 🔥!

Supported Emojis

  • ❤️ → ❤️
  • 🔥 → 🔥
  • 👍 → 👍
  • 🚀 → 🚀
  • → ⭐
  • 😄 → 😊
  • 🎉 → 🎉
  • ⚠️ → ⚠️
  • :check: → ✅
  • → ❌

And many more! BunPress uses the comprehensive emoji shortcode database.

Math Equations

BunPress supports both inline and block math equations using LaTeX syntax.

Inline Math

The Pythagorean theorem: $a^2 + b^2 = c^2$

The Pythagorean theorem: $a2 + b2 = c^2$

Block Math

$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$

$

\int_{-\infty}{\infty} e{-x^2} dx = \sqrt{\pi}

$

Mixed Equations

When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$:

$
x = {-b \pm \sqrt{b^2-4ac} \over 2a}
$

When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$:

$

x = {-b \pm \sqrt{b^2-4ac} \over 2a}

$

Syntax Highlighting

BunPress provides advanced syntax highlighting powered by Shiki, supporting multiple languages with beautiful themes and interactive features.

Basic Syntax Highlighting

BunPress supports syntax highlighting for over 40 programming languages:

interface User {
  name: string
  age: number
  email?: string
}

const user: User = {
  name:'John Doe' 'John Doe',
  age: 30,
  email:'john@example.com' 'john@example.com'
}

function greet(user: User): string {
  return `Hello, ${user.name}!`
}

console.log(greet(user))

Copy-to-Clipboard

Hover over any code block to see the copy button in the top-right corner. Click to copy the code to your clipboard with visual feedback.

const { readFile } = require('node:fs''node:fs').promises

async function readConfig() {
  try {
    const config = await readFile('./config.json''./config.json','utf8' 'utf8')
    return JSON.parse(config)
  }
  catch (error) {
    console.error('Failed to read config:''Failed to read config:', error)
    return {}
  }
}

Line Numbers

Add :line-numbers to enable line numbers:

1function calculateTotal(items) {
2  let total = 0
3  for (const item of items) {
4    total += item.price * item.quantity
5  }
6  return total
7}
8
9const items = [
10  { name:'Apple' 'Apple', price: 1.50, quantity: 3 },
11  { name:'Banana' 'Banana', price: 0.75, quantity: 2 }
12]
13
14console.log(calculateTotal(items))

Line Highlighting

Highlight specific lines using curly braces:

def process_data(data):
    # This line is highlighted
    if not data:
        return None

    # These lines are highlighted
    processed = []
    for item in data:
        processed.append(item.upper())

    return processed

Combined Features

You can combine line numbers with highlighting:

1import { Component } from'react' 'react'
2
3interface Props {
4  title: string
5  items: string[]
6}
7
8export default function ListComponent({ title, items }: Props) {
9  // This line is highlighted
10  return (
11    <div>
12      <h2>{title}</h2>
13      <ul>
14        {/* These lines are highlighted */}
15        {items.map((item, index) => (
16          <li key={index}>{item}</li>
17        ))}
18      </ul>
19    </div>
20  )
21}

Multiple Languages

BunPress supports a wide range of programming languages:

Web Technologies:

<div class="container">
  <h1>Hello World</h1>
  <p>This is a sample HTML document.</p>
</div>
.highlighted {
  background-color: yellow;
  padding: 0.5em;
  border-radius: 0.375rem;
}

.error {
  color: red;
  font-weight: bold;
}

Backend Languages:

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Databases:

SELECT
    u.id,
    u.username,
    u.email,
    p.first_name,
    p.last_name
FROM users u
LEFT JOIN profiles p ON u.id = p.user_id
WHERE u.active = true
ORDER BY u.created_at DESC

Configuration Files:

version: '3.8'
services:
  web:
    build: .
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=production

File Information

Add file names to code blocks:

export function formatDate(date: Date): string {
  return date.toLocaleDateString('en-US''en-US', {
    year:'numeric' 'numeric',
    month:'long' 'long',
    day:'numeric' 'numeric'
  })
}

Diff Highlighting

Highlight changes in diff format:

+ const newFeature = 'This line was added'
+ const enhancedFunction = () => {
+   console.log('Enhanced functionality')
+ }

- const oldFeature = 'This line was removed'
- const basicFunction = () => {
-   console.log('Basic functionality')
- }

  const unchanged = 'This line stayed the same'

Combined Extensions

All extensions work seamlessly together:

<div class="custom-block tip">
  <p class="custom-block-title">TIP</p>
  <div class="custom-block-content">
    <p>Here's a 🔥 tip with math: $E = mc^2{{ content }}lt;/p>
<p><code>`</code>javascript{2}</p>
<p>function energy(mass) {</p>
<p>  const c = 299792458 // speed of light</p>
<p>  return mass <em> c </em> c</p>
<p>}</p>
<p><code>`</code></p>
<p>Try it out! 🚀</p>
  </div>
</div>

TIP

Here's a 🔥 tip with math: $E = mc^2$

`javascript{2}

function energy(mass) {

const c = 299792458 // speed of light

return mass c c

}

`

Try it out! 🚀

GitHub Alerts

BunPress supports GitHub-flavored alert syntax for creating attention-grabbing callouts.

Available Alert Types

<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>Essential information that users should know.</p>
  </div>
</div>

<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>Helpful advice for doing things better or more easily.</p>
  </div>
</div>

<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>Key information users need to know to achieve their goal.</p>
  </div>
</div>

<div class="github-alert github-alert-warning">
  <p class="github-alert-title">
    <svg class="github-alert-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>
    Warning
  </p>
  <div class="github-alert-content">
    <p>Urgent information that requires immediate attention to avoid problems.</p>
  </div>
</div>

<div class="github-alert github-alert-caution">
  <p class="github-alert-title">
    <svg class="github-alert-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>
    Caution
  </p>
  <div class="github-alert-content">
    <p>Potential risks or negative outcomes of certain actions.</p>
  </div>
</div>

Note

Essential information that users should know.

Tip

Helpful advice for doing things better or more easily.

Important

Key information users need to know to achieve their goal.

Warning

Urgent information that requires immediate attention to avoid problems.

Caution

Potential risks or negative outcomes of certain actions.

Alert Features

  • Icon indicators: Each alert type has a distinctive icon
  • Color coding: Visual distinction with semantic colors
  • Markdown support: Full markdown rendering inside alerts including links, code, lists
  • Nested content: Supports multi-line content with proper formatting

Inline Badges

Add inline badges to highlight version numbers, status indicators, or tags.

Basic Badge Syntax

Available in <span class="badge badge-tip" style="display: inline-block; padding: 2px 8px; font-size: 0.85em; font-weight: 600; border-radius: 4px; background: #dcfce7; color: #14532d; border: 1px solid #22c55e; margin: 0 4px; vertical-align: middle;">v2.0+</span>
<span class="badge badge-warning" style="display: inline-block; padding: 2px 8px; font-size: 0.85em; font-weight: 600; border-radius: 4px; background: #fef3c7; color: #78350f; border: 1px solid #f59e0b; margin: 0 4px; vertical-align: middle;">deprecated</span>
<span class="badge badge-danger" style="display: inline-block; padding: 2px 8px; font-size: 0.85em; font-weight: 600; border-radius: 4px; background: #fee2e2; color: #7f1d1d; border: 1px solid #ef4444; margin: 0 4px; vertical-align: middle;">breaking</span>
<span class="badge badge-info" style="display: inline-block; padding: 2px 8px; font-size: 0.85em; font-weight: 600; border-radius: 4px; background: #e0f2fe; color: #0c4a6e; border: 1px solid #0ea5e9; margin: 0 4px; vertical-align: middle;">beta</span>

Available in v2.0+

deprecated

breaking

beta

Badge Types

  • tip (green): New features, recommended practices
  • warning (yellow): Deprecation notices, caution
  • danger (red): Breaking changes, critical warnings
  • info (blue): General information, neutral status

Badge in Headings

## New Feature <span class="badge badge-tip" style="display: inline-block; padding: 2px 8px; font-size: 0.85em; font-weight: 600; border-radius: 4px; background: #dcfce7; color: #14532d; border: 1px solid #22c55e; margin: 0 4px; vertical-align: middle;">2.0+</span>

New Feature 2.0+

Code Groups

Create tabbed code blocks to show multiple language examples or alternative implementations.

Basic Code Group

<div class="code-group" id="code-group-d89s7gune">
  <div class="code-group-tabs">
    <button class="code-group-tab active" onclick="switchCodeTab('code-group-d89s7gune', 0)">JavaScript</button><button class="code-group-tab " onclick="switchCodeTab('code-group-d89s7gune', 1)">TypeScript</button><button class="code-group-tab " onclick="switchCodeTab('code-group-d89s7gune', 2)">Python</button>
  </div>
  <div class="code-group-panels">
    <div class="code-group-panel active" data-panel="0">
  <pre data-lang="javascript"><code class="language-javascript"><span class="token storage-type-js" style="color: #cf222e">const</span> <span class="token source-js" style="">config</span> <span class="token keyword-operator-js" style="color: #cf222e">=</span> <span class="token source-js" style="">{</span>
  <span class="token source-js" style="">port</span><span class="token keyword-operator-js" style="color: #cf222e">:</span> <span class="token constant-numeric-js" style="color: #0550ae">3000</span><span class="token source-js" style="">,</span>
  <span class="token source-js" style="">host</span><span class="token keyword-operator-js" style="color: #cf222e">:</span><span class="token string-quoted-double-js" style="color: #0a3069">&#039;localhost&#039;</span> 'localhost'
<span class="token source-js" style="">}</span></code></pre>
</div>
<div class="code-group-panel " data-panel="1">
  <pre data-lang="typescript"><code class="language-typescript"><span class="token storage-type-ts" style="color: #cf222e">interface</span> <span class="token source-ts" style="">Config</span> <span class="token source-ts" style="">{</span>
  <span class="token source-ts" style="">port</span><span class="token keyword-operator-ts" style="color: #cf222e">:</span> <span class="token storage-type-ts" style="color: #cf222e">number</span>
  <span class="token source-ts" style="">host</span><span class="token keyword-operator-ts" style="color: #cf222e">:</span> <span class="token storage-type-ts" style="color: #cf222e">string</span>
<span class="token source-ts" style="">}</span>

<span class="token storage-type-ts" style="color: #cf222e">const</span> <span class="token source-ts" style="">config</span><span class="token keyword-operator-ts" style="color: #cf222e">:</span> <span class="token source-ts" style="">Config</span> <span class="token keyword-operator-ts" style="color: #cf222e">=</span> <span class="token source-ts" style="">{</span>
  <span class="token source-ts" style="">port</span><span class="token keyword-operator-ts" style="color: #cf222e">:</span> <span class="token constant-numeric-ts" style="color: #0550ae">3000</span><span class="token source-ts" style="">,</span>
  <span class="token source-ts" style="">host</span><span class="token keyword-operator-ts" style="color: #cf222e">:</span><span class="token string-quoted-double-ts" style="color: #0a3069">&#039;localhost&#039;</span> 'localhost'
<span class="token source-ts" style="">}</span></code></pre>
</div>
<div class="code-group-panel " data-panel="2">
  <pre data-lang="python"><code class="language-python"><span class="line">config = {</span>
<span class="line">    &#39;port&#39;: 3000,</span>
<span class="line">    &#39;host&#39;: &#39;localhost&#39;</span>
<span class="line">}</span>
<span class="line"></span></code></pre>
</div>
  </div>
</div>
const config = {
  port: 3000,
  host:'localhost' 'localhost'
}
interface Config {
  port: number
  host: string
}

const config: Config = {
  port: 3000,
  host:'localhost' 'localhost'
}
config = {
    'port': 3000,
    'host': 'localhost'
}

Features

  • Tab navigation: Click tabs to switch between code examples
  • Active state: First tab is active by default
  • Syntax highlighting: Full support for all languages
  • Line numbers: Works with :line-numbers modifier
  • Line highlighting: Compatible with {1,3-5} syntax

Code File Imports

Import code snippets directly from files in your codebase with support for line ranges and named regions.

Full File Import

<<< ./examples/config.ts

Line Range Import

<<< ./examples/server.ts{10-25}

Import lines 10-25 from the file.

Named Region Import

<<< ./examples/api.ts{#setup}

Imports content between region markers in the file:

// #region setup
const app = express()
app.use(express.json())
// #endregion setup

Features

  • Live imports: Code is imported at build time from actual files
  • Syntax detection: Automatically detects language from file extension
  • Error handling: Gracefully handles missing files or invalid regions
  • Line numbers: Add :line-numbers after the path
  • Highlighting: Combine with {1,3-5} after language for highlights

Examples

<<< ./src/utils/helper.ts:line-numbers
<<< ./src/api/routes.ts{#auth}:line-numbers
<<< ./examples/demo.js{1-20}

Markdown File Inclusion

Include entire markdown files or specific sections in your documentation to promote reusability and maintainability.

Full File Inclusion

<!--@include: ./components/intro.md-->

Line Range Inclusion

<!--@include: ./guide.md{1-10}-->

Includes only lines 1-10 from the file.

Named Region Inclusion

<!--@include: ./api-docs.md{#authentication}-->

Includes content between region markers:

<!-- #region authentication -->
## Authentication

Your authentication content here...
<!-- #endregion -->

Features

  • Recursive includes: Included files can include other files
  • Circular reference protection: Prevents infinite loops
  • Full markdown processing: Included content is processed with all BunPress features
  • Path resolution: Relative paths resolved from the including file's directory
  • Error handling: Missing files or invalid regions fail gracefully

Use Cases

  • Shared content: Reuse common sections across multiple pages
  • Modular documentation: Break large docs into manageable files
  • Version-specific content: Include different content based on context
  • Multi-language docs: Share code examples across translations

Configuration

The syntax highlighting features are enabled by default and require no additional configuration. However, you can customize the behavior through your bunpress.config.ts:

export default {
  markdown: {
    // Custom marked options for advanced configuration
    markedOptions: {
      // Configure marked extensions
    }
  }
}

Supported Languages

BunPress supports syntax highlighting for the following languages out of the box:

  • Web Technologies: JavaScript, TypeScript, HTML, CSS, JSON, YAML
  • Backend Languages: Python, Go, Rust, Ruby, PHP, Java, C/C++, C#
  • Databases: SQL, GraphQL
  • DevOps: Bash, Shell, Docker, Nginx
  • Data Science: R, MATLAB
  • Mobile: Swift, Kotlin, Dart
  • Other: Markdown, XML, TOML, INI, Diff, Log files

Theme Support

The syntax highlighting uses Shiki with the following built-in themes:

  • light-plus (default)
  • dark-plus
  • Additional themes can be configured by modifying the plugin setup

Performance Notes

  • Shiki highlighter is initialized once at build start for optimal performance
  • Code blocks are cached to avoid re-processing identical content
  • Large code blocks are handled efficiently with proper HTML structure

Browser Compatibility

  • Modern browsers: Full Clipboard API support with visual feedback
  • Legacy browsers: Fallback to document.execCommand for copying
  • Progressive enhancement: Features gracefully degrade on older browsers

Accessibility

All syntax highlighting features are designed with accessibility in mind:

  • Copy buttons have proper ARIA labels and keyboard navigation
  • Line numbers are properly associated with their content
  • Color schemes follow WCAG guidelines for contrast
  • Screen reader friendly markup structure