shiki
Shiki 3+ syntax highlighting. Use when highlighting code blocks, MDX content, or building code editors.
When & Why to Use This Skill
Shiki is a professional-grade syntax highlighter based on TextMate grammars, providing the same high-quality code rendering used in VS Code. This skill enables developers to integrate Shiki 3+ into web applications, documentation sites, and MDX pipelines, offering features like high-performance rendering, custom themes (e.g., Nord, GitHub Dark), and advanced AST transformers for fine-grained code block customization.
Use Cases
- Technical Documentation: Generate beautiful, theme-aware syntax highlighting for documentation sites built with modern frameworks like Astro, VitePress, or Next.js.
- MDX Content Processing: Use the @shikijs/rehype integration to automatically transform code blocks in Markdown files into highlighted HTML during the build process.
- Custom Code Editors: Implement server-side or client-side code highlighting for developer-focused web tools and playgrounds using the lightweight v3 engine.
- Advanced Code Annotations: Leverage Shiki Transformers to add specialized features like line highlighting, diff notations, and custom CSS classes to rendered code snippets.
| name | shiki |
|---|---|
| description | Shiki 3+ syntax highlighting. Use when highlighting code blocks, MDX content, or building code editors. |
Shiki 3+
Create highlighter — v3 pattern
import { createHighlighter } from 'shiki'
const highlighter = await createHighlighter({
themes: ['nord', 'github-dark'],
langs: ['typescript', 'python'],
})
const html = highlighter.codeToHtml('const x = 1', {
lang: 'typescript',
theme: 'nord',
})
// NOT getHighlighter — that's v1
Shorthand functions — no highlighter needed
import { codeToHtml, codeToTokens, codeToHast } from 'shiki'
// Direct usage (creates internal highlighter)
const html = await codeToHtml('const x = 1', {
lang: 'typescript',
theme: 'github-dark',
})
const { tokens } = await codeToTokens(code, { lang: 'ts', theme: 'nord' })
const hast = await codeToHast(code, { lang: 'css', theme: 'min-dark' })
Rehype integration — @shikijs/rehype
import rehypeShiki from '@shikijs/rehype'
import remarkRehype from 'remark-rehype'
import { unified } from 'unified'
const processor = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeShiki, {
themes: {
light: 'github-light',
dark: 'github-dark',
},
// Inline code: `code{:lang}`
inline: 'tailing-curly-colon',
})
Transformers — hook into rendering
import { transformerNotationHighlight } from '@shikijs/transformers'
const html = await codeToHtml(code, {
lang: 'ts',
theme: 'nord',
transformers: [
transformerNotationHighlight(), // [!code highlight]
{
// Custom transformer
line(node, line) {
node.properties['data-line'] = line
},
code(node) {
this.addClassToHast(node, 'my-code-block')
},
},
],
})
Fine-grained bundles — v3 engine system
import { createHighlighterCore } from 'shiki/core'
import { createOnigurumaEngine } from 'shiki/engine/oniguruma'
const highlighter = await createHighlighterCore({
themes: [import('@shikijs/themes/nord')],
langs: [import('@shikijs/langs/typescript')],
engine: createOnigurumaEngine(() => import('shiki/wasm')),
})
// NOT loadWasm from 'shiki' — that's v1/v2
Avoid
getHighlighter()→createHighlighter()loadWasmfrom'shiki'→createOnigurumaEnginefrom'shiki/engine/oniguruma'@shikijs/compat→ discontinued, use main packagepostprocesshook in rehype → doesn't run, useroothook insteadcreatedBundledHighlighter(fn, fn)→ single object argument in v3