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:
<divclass"container"
<h1Hello World</h1
<pThis 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">'localhost'</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">'localhost'</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"> 'port': 3000,</span>
<span class="line"> 'host': 'localhost'</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-numbersmodifier - 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-numbersafter 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.execCommandfor 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