Syntax Highlighting
The comark/plugins/highlight plugin provides beautiful syntax highlighting for code blocks using Shiki. It supports multiple themes, line highlighting, and on-demand language loading for optimal performance.
Installation
The highlight plugin is built into Comark and uses Shiki as a peer dependency. Install the required packages:
npm install shiki
pnpm add shiki
yarn add shiki
bun add shiki
Basic Usage
Import themes and languages from @shikijs/themes and @shikijs/langs for type safety and better tree-shaking:
With Parse API
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const content = `
\`\`\`javascript
function hello() {
console.log("Hello, World!")
}
\`\`\`
`
// Enable syntax highlighting with themes
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})
]
})
With Specific Languages
Import only the languages you need for optimal bundle size:
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import python from '@shikijs/langs/python'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
},
languages: [javascript, typescript, python]
})
]
})
With Vue
<script setup lang="ts">
import { Comark } from '@comark/vue'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const plugins = [
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})
]
const md = `
\`\`\`javascript
const greeting = "Hello World"
console.log(greeting)
\`\`\`
`
</script>
<template>
<Suspense>
<Comark :plugins="plugins" :markdown="md" />
</Suspense>
</template>
<style scoped>
.dark :deep(.shiki span) {
color: var(--shiki-dark) !important;
}
</style>
With React
import { Comark } from '@comark/react'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const content = `
\`\`\`javascript
const greeting = "Hello World"
console.log(greeting)
\`\`\`
`
export default function App() {
return (
<Comark
plugins={[
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})
]}
>
{content}
</Comark>
)
}
Features
1. Dual-Theme Support
Highlight code with different themes for light and dark modes:
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import materialLight from '@shikijs/themes/material-theme-lighter'
import materialDark from '@shikijs/themes/material-theme-palenight'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: materialLight,
dark: materialDark
}
})
]
})
Popular themes (import from @shikijs/themes):
github-light/github-dark- GitHub's official themesmaterial-theme-lighter/material-theme-palenight(default) - Material Design themesnord- Arctic-inspired color paletteone-dark-pro- Atom's iconic One Dark themedracula- Dark theme with vibrant colorsmonokai- Sublime Text's classic themecatppuccin-latte/catppuccin-mocha- Soothing pastel themestokyo-night/tokyo-night-storm- Clean, dark themessolarized-light/solarized-dark- Precision colors for readability- And many more - View all available themes
Using multiple themes:
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
import tokyoNight from '@shikijs/themes/tokyo-night-storm'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark,
// Add custom theme names for specific use cases
dim: tokyoNight
}
})
]
})
2. Language Detection
Automatically detects and highlights 180+ languages:
```javascript
const x = 42
```
```typescript
const x: number = 42
```
```python
x = 42
```
```rust
let x: i32 = 42;
```
3. Line Highlighting
Highlight specific lines using {line-numbers} syntax:
```javascript {1-3,5}
function example() {
const a = 1 // highlighted
const b = 2 // highlighted
const c = 3 // highlighted
return a + b + c // highlighted
}
```
Output:
Lines 1-3 and 5 will have the highlight class applied.
4. Filename Metadata
Display filenames above code blocks:
```javascript [server.js]
const express = require('express')
const app = express()
```
5. Language Loading
Import languages from @shikijs/langs for better tree-shaking and type safety:
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubDark from '@shikijs/themes/github-dark'
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import python from '@shikijs/langs/python'
import rust from '@shikijs/langs/rust'
const result = await parse(content, {
plugins: [
highlight({
themes: { dark: githubDark },
languages: [javascript, typescript, python, rust]
})
]
})
Common language imports:
// Web
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import jsx from '@shikijs/langs/jsx'
import tsx from '@shikijs/langs/tsx'
import vue from '@shikijs/langs/vue'
import html from '@shikijs/langs/html'
import css from '@shikijs/langs/css'
// Backend
import python from '@shikijs/langs/python'
import rust from '@shikijs/langs/rust'
import go from '@shikijs/langs/go'
import java from '@shikijs/langs/java'
// Data
import json from '@shikijs/langs/json'
import yaml from '@shikijs/langs/yaml'
import sql from '@shikijs/langs/sql'
// Shell
import bash from '@shikijs/langs/bash'
import shell from '@shikijs/langs/shell'
Why import directly?
- ✅ Type Safety: TypeScript autocomplete for themes and languages
- ✅ Tree Shaking: Only bundle the themes/languages you use
- ✅ No Typos: Import errors caught at build time
- ✅ Smaller Bundle: Import only what you need
6. Pre Styles
Add background and foreground colors to <pre> elements:
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
},
preStyles: true // Adds background/foreground colors
})
]
})
Configuration Options
import type { BundledLanguage, BundledTheme } from 'shiki'
interface HighlightOptions {
// Whether to use the default language definitions
// @default true
registerDefaultLanguages?: boolean
// Whether to use the default theme definitions
// @default true
registerDefaultThemes?: boolean
// Theme configuration - import from @shikijs/themes
themes?: Record<string, BundledTheme>
// Languages to include - import from @shikijs/langs
languages?: BundledLanguage[]
// Add inline styles to <pre> elements
preStyles?: boolean
}
Option Details
registerDefaultLanguages
Controls whether to register a set of commonly-used languages. When true (default), these languages are automatically registered: vue, typescript, javascript, mdc, markdown, comark, tsx, bash, json, yaml. For any other languages, you need to provide them via the languages option.
When false, no languages are registered by default - you must provide all languages you need.
// Don't register default languages, only use specified ones
highlight({
registerDefaultLanguages: false,
languages: [javascript, typescript, python]
})
Default languages registered (when true):
vue,typescript,javascript,mdc,tsx,bash,json,yaml
Use case: Set to false when you want complete control over which languages are bundled, or when you don't need any of the default languages.
registerDefaultThemes
Controls whether to register the default Material themes. When true (default), these themes are automatically registered: material-theme-lighter (light) and material-theme-palenight (dark). For any other themes, you need to provide them via the themes option.
When false, no themes are registered by default - you must provide all themes you need.
// Don't register default themes, only use specified ones
highlight({
registerDefaultThemes: false,
themes: {
light: githubLight,
dark: githubDark
}
})
Default themes registered (when true):
material-theme-lighter(light mode)material-theme-palenight(dark mode)
Use case: Set to false for maximum bundle size optimization when using custom themes and don't need the Material themes.
themes
Theme configuration for light and dark modes. Import themes from @shikijs/themes.
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})
Default: { light: materialThemeLighter, dark: materialThemePalenight }
languages
Array of languages to preload. Import from @shikijs/langs. If not specified, languages are loaded on-demand when needed.
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
highlight({
languages: [javascript, typescript]
})
Default: undefined (load on demand)
preStyles
Whether to add inline background and foreground color styles to <pre> elements based on the theme.
highlight({
preStyles: true
})
Default: false
Default Configuration
{
registerDefaultLanguages: true, // Registers: vue, typescript, javascript, mdc, tsx, bash, json, yaml
registerDefaultThemes: true, // Registers: material-theme-lighter, material-theme-palenight
themes: {
light: materialThemeLighter,
dark: materialThemePalenight
},
languages: undefined, // Only default languages registered, add more via this option
preStyles: false
}
What gets registered by default:
- Languages:
vue,typescript,javascript,mdc,tsx,bash,json,yaml(8 languages) - Themes:
material-theme-lighter(light),material-theme-palenight(dark)
To add more languages, provide them via the languages option:
import python from '@shikijs/langs/python'
import rust from '@shikijs/langs/rust'
highlight({
// Defaults (vue, ts, js, mdc, tsx, bash, json, yaml) are still registered
languages: [python, rust] // Add Python and Rust
})
For smallest bundle, disable defaults and only include what you need:
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
highlight({
registerDefaultLanguages: false, // Don't register any defaults
registerDefaultThemes: false, // Don't register Material themes
languages: [javascript, typescript],
themes: {
light: githubLight,
dark: githubDark
}
})
Examples
GitHub Theme
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})
]
})
Single Theme
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import nord from '@shikijs/themes/nord'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: nord,
dark: nord
}
})
]
})
With Pre Styles
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const result = await parse(content, {
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
},
preStyles: true
})
]
})
With Specific Languages
import { parse } from 'comark'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import python from '@shikijs/langs/python'
import rust from '@shikijs/langs/rust'
const result = await parse(content, {
plugins: [
highlight({
languages: [javascript, typescript, python, rust],
themes: {
light: githubLight,
dark: githubDark
}
})
]
})
Documentation Site
<script setup lang="ts">
import { defineComarkComponent } from '@comark/vue'
import highlight from 'comark/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const DocsContent = defineComarkComponent({
name: 'DocsContent',
plugins: [
highlight({
themes: {
light: githubLight,
dark: githubDark
},
preStyles: true
})
]
})
</script>
<template>
<Suspense>
<DocsContent>{{ content }}</DocsContent>
</Suspense>
</template>
Blog with Code Examples
import { defineComarkComponent } from '@comark/react'
import highlight from 'comark/plugins/highlight'
import materialLight from '@shikijs/themes/material-theme-lighter'
import dracula from '@shikijs/themes/dracula'
export const BlogPost = defineComarkComponent({
name: 'BlogPost',
plugins: [
highlight({
themes: {
light: materialLight,
dark: dracula
}
})
]
})
// Usage
export default function Post({ content }) {
return (
<article className="prose">
<BlogPost>{content}</BlogPost>
</article>
)
}
Live Example
See the highlight plugin in action with a comprehensive example showcasing multiple languages and themes:
Vue + Vite Highlight Example
Complete example with 10+ languages, dual-theme support, and theme toggle. Includes JavaScript, TypeScript, Python, Rust, Go, SQL, and more.
Features:
- ✨ Dual-theme support (light/dark)
- 🎨 10+ language examples
- 🔄 Theme toggle button
- 📦 Ready to run with
pnpm dev
Styling
CSS Variables
Shiki generates inline styles, but you can override with CSS:
/* Override code block styles */
pre.shiki {
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
}
/* Line highlighting */
.line.highlight {
background-color: rgba(255, 255, 0, 0.1);
display: block;
margin: 0 -1rem;
padding: 0 1rem;
}
Dark Mode Integration
For frameworks with dark mode support:
/* Tailwind CSS example */
@media (prefers-color-scheme: dark) {
pre.shiki {
/* Dark theme styles automatically applied by Shiki */
}
}
Performance
The highlight plugin is optimized for performance:
- Singleton Highlighter: Creates one Shiki instance shared across all code blocks
- On-Demand Loading: Languages loaded only when needed
- Theme Caching: Themes loaded once and reused
- Async Processing: Highlighting happens during parse, not render
- Graceful Fallbacks: Falls back to plain text if language not supported
- Tree Shaking: Import only the languages and themes you use
## Supported Languages
Shiki supports 180+ languages including:
**Web:**
- JavaScript, TypeScript, JSX, TSX
- HTML, CSS, SCSS, SASS, Less
- Vue, Svelte, Astro
**Backend:**
- Python, Ruby, PHP, Go
- Java, Kotlin, Scala
- Rust, C, C++, C#
**Data:**
- JSON, YAML, TOML, XML
- SQL, GraphQL
**Shell:**
- Bash, Shell, PowerShell, Batch
**Config:**
- Dockerfile, Nginx, Apache
- Git Config, .env
[View full language list](https://shiki.style/languages)
## Troubleshooting
### "Shiki is not installed" Error
Make sure all required packages are installed:
```bash [Terminal]
npm install shiki @shikijs/themes @shikijs/langs
TypeScript Errors
If you get TypeScript errors about theme/language imports, ensure you're importing from the correct packages:
// ✅ Correct
import githubDark from '@shikijs/themes/github-dark'
import javascript from '@shikijs/langs/javascript'
// ❌ Wrong (old approach)
themes: { dark: 'github-dark' }
languages: ['javascript']
See Also
- Markdown Syntax - Code block syntax reference
- Parse API - Parsing options
- Vue Rendering - Using with Vue
- React Rendering - Using with React
- Shiki Documentation - Shiki features and themes