The comark/plugins/highlight plugin provides syntax highlighting for code blocks using Shiki. It supports multiple themes, line highlighting, and on-demand language loading.
npm install shikiUsage
Import themes from @shikijs/themes for type safety and tree-shaking:
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
}
})
]
})With framework components:
<script setup lang="ts">
import { Comark } from '@comark/vue'
import highlight from '@comark/vue/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
const plugins = [
highlight({
themes: { light: githubLight, dark: githubDark }
})
]
</script>
<template>
<Suspense>
<Comark :plugins="plugins">{{ content }}</Comark>
</Suspense>
</template>
<style scoped>
html.dark .shiki :deep(span) {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
</style>import { Comark } from '@comark/react'
import highlight from '@comark/react/plugins/highlight'
import githubLight from '@shikijs/themes/github-light'
import githubDark from '@shikijs/themes/github-dark'
<Comark
plugins={[highlight({ themes: { light: githubLight, dark: githubDark } })]}
>
{content}
</Comark>Features
Dual-Theme Support
Highlight code with different themes for light and dark modes. Both palettes are embedded as CSS custom properties — no flash on theme switch. See all available themes →
highlight({
themes: {
light: githubLight,
dark: githubDark
}
})Language Detection
Comark reads the language from the code fence info string and highlights accordingly. Languages are loaded on demand by default. See all 180+ supported languages →
```typescript
const x: number = 42
```Line Highlighting
Highlight specific lines using {line-numbers} syntax:
```javascript {2-3,5}
function example() {
const a = 1 // highlighted
const b = 2 // highlighted
const c = 3
return a + b + c // highlighted
}
```Lines receive the .highlight class — see Styling for the required CSS.
Filename Metadata
Display a filename label above the code block:
```javascript [server.js]
const app = express()
```Language Loading
Import languages from @shikijs/langs to preload them and gain type safety:
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import python from '@shikijs/langs/python'
highlight({
languages: [javascript, typescript, python]
})languages, unregistered languages are loaded on demand. Use registerDefaultLanguages: false with an explicit languages array for the smallest bundle.Transformers
Pass any Shiki transformer via transformers to add diff annotations, focus lines, or custom classes:
import { transformerNotationDiff } from '@shikijs/transformers'
highlight({
themes: { light: githubLight, dark: githubDark },
transformers: [transformerNotationDiff()]
})The most powerful transformer is @shikijs/twoslash — it runs the TypeScript compiler on your code blocks to add inline type tooltips and error annotations.
Pre Styles
Set preStyles: true to add inline background and foreground colors to <pre> elements based on the active theme.
API
highlight(options?)
Returns a ComarkPlugin that enables Shiki syntax highlighting.
Parameters:
options?- Optional configuration — see Options
Returns: ComarkPlugin
Options
| Option | Type | Default | Description |
|---|---|---|---|
themes | object | Material themes | Light and dark theme registrations |
languages | LanguageRegistration[] | undefined | Languages to preload |
transformers | ShikiTransformer[] | undefined | Shiki transformers applied to every block |
preStyles | boolean | false | Add inline background/foreground styles to <pre> |
registerDefaultLanguages | boolean | true | Register the built-in default language set |
registerDefaultThemes | boolean | true | Register the built-in Material themes |
themes
Theme configuration for light and dark modes. Import 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
Languages to preload. Import from @shikijs/langs. Without this option, languages are loaded on demand.
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
highlight({
languages: [javascript, typescript]
})Default: undefined
transformers
An array of Shiki transformers applied to every highlighted block.
import { transformerNotationDiff, transformerNotationHighlight } from '@shikijs/transformers'
highlight({
transformers: [
transformerNotationDiff(), // [!code ++] / [!code --]
transformerNotationHighlight(), // [!code highlight]
]
})Default: undefined
preStyles
Add inline background and foreground color styles to <pre> elements based on the active theme.
highlight({ preStyles: true })Default: false
registerDefaultLanguages
When true, these languages are pre-registered: vue, tsx, svelte, astro, typescript, javascript, mdc, bash, json, yaml. Set to false to control the language set entirely via languages.
highlight({
registerDefaultLanguages: false,
languages: [javascript, typescript]
})Default: true
registerDefaultThemes
When true, material-theme-lighter (light) and material-theme-palenight (dark) are pre-registered. Set to false when using only custom themes.
highlight({
registerDefaultThemes: false,
themes: { light: githubLight, dark: githubDark }
})Default: true
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 } })]
})Minimal Bundle
Disable defaults and import only what you need:
import javascript from '@shikijs/langs/javascript'
import typescript from '@shikijs/langs/typescript'
import githubDark from '@shikijs/themes/github-dark'
highlight({
registerDefaultLanguages: false,
registerDefaultThemes: false,
languages: [javascript, typescript],
themes: { dark: githubDark }
})With Transformers
import {
transformerNotationDiff,
transformerNotationHighlight,
transformerNotationFocus,
} from '@shikijs/transformers'
highlight({
themes: { light: githubLight, dark: githubDark },
transformers: [
transformerNotationDiff(), // [!code ++] / [!code --]
transformerNotationHighlight(), // [!code highlight]
transformerNotationFocus(), // [!code focus]
]
})See the Twoslash guide for TypeScript-powered type tooltips and error annotations in code blocks.
Live Examples
Vue + Vite Highlight
Vue + Vite Twoslash
Styling
Shiki outputs tokens as <span class="line"> elements inside a <pre class="shiki"> block.
Line Highlight
Lines set with {1,3-5} syntax receive the .highlight class:
.shiki span.line.highlight {
background-color: rgba(255, 255, 0, 0.1);
display: inline-block;
width: calc(100% + 2rem);
margin: 0 -1rem;
padding: 0 1rem;
}Dark Mode
When both light and dark themes are provided, Shiki embeds both palettes as CSS custom properties on every <span>. Activate the dark palette based on your project's dark-mode class:
html.dark .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}In Vue scoped styles, use :deep() to reach Shiki spans:
<style scoped>
html.dark .shiki :deep(span) {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
</style>