Core Plugins

Syntax Highlighting

Plugin for syntax highlighting code blocks using Shiki with multi-theme support.

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

Basic Usage

Import themes and languages from @shikijs/themes and @shikijs/langs for type safety and better tree-shaking:

With Parse API

parse.ts
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:

parse.ts
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

App.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

App.tsx
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:

parse.ts
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 themes
  • material-theme-lighter / material-theme-palenight (default) - Material Design themes
  • nord - Arctic-inspired color palette
  • one-dark-pro - Atom's iconic One Dark theme
  • dracula - Dark theme with vibrant colors
  • monokai - Sublime Text's classic theme
  • catppuccin-latte / catppuccin-mocha - Soothing pastel themes
  • tokyo-night / tokyo-night-storm - Clean, dark themes
  • solarized-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:

parse.ts
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:

config.ts
// 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'

View all 180+ languages →

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:

parse.ts
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.

config.ts
// 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.

config.ts
// 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.

config.ts
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.

config.ts
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.

config.ts
highlight({
  preStyles: true
})

Default: false

Default Configuration

config.ts
{
  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:

config.ts
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:

config.ts
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

parse.ts
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

parse.ts
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

parse.ts
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

parse.ts
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

DocsContent.vue
<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

BlogPost.tsx
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

View on GitHub →

Styling

CSS Variables

Shiki generates inline styles, but you can override with CSS:

styles.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:

styles.css
/* 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:

  1. Singleton Highlighter: Creates one Shiki instance shared across all code blocks
  2. On-Demand Loading: Languages loaded only when needed
  3. Theme Caching: Themes loaded once and reused
  4. Async Processing: Highlighting happens during parse, not render
  5. Graceful Fallbacks: Falls back to plain text if language not supported
  6. 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:

config.ts
// ✅ 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

Copyright © 2026