remark-shiki-highlight-api

Remark plugin for high-performance syntax highlighting in Markdown using the CSS Highlights API with Shiki

typescriptremarkshikimarkdowncss-highlights-api
View on GitHub →

A Remark plugin that brings high-performance CSS Highlights API syntax highlighting to Markdown/MDX workflows. Built on top of shiki-highlight-api to provide seamless integration with Astro, Next.js, and other Remark-based static site generators.

🎯 Why This Plugin?

Static site generators like Astro and Next.js use Remark to process Markdown. Traditional syntax highlighting plugins create massive DOM trees full of <span> elements, which:

  • Bloat your HTML bundle size
  • Slow down initial page render
  • Increase memory usage
  • Make theme switching expensive

This plugin uses the CSS Highlights API instead, achieving 90%+ fewer DOM nodes and dramatically faster rendering for code-heavy documentation sites.

🚀 Perfect For

  • Documentation sites with extensive code examples
  • Technical blogs built with Astro, Next.js, or Gatsby
  • Tutorial platforms like Code Like It’s 198x
  • MDX-based sites needing performant syntax highlighting
  • Any Markdown workflow where performance matters

📦 Installation

npm install remark-shiki-highlight-api

🔧 Usage with Astro

// astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkShikiHighlight from 'remark-shiki-highlight-api';

export default defineConfig({
  markdown: {
    remarkPlugins: [
      [remarkShikiHighlight, {
        theme: 'github-dark',
        langs: ['javascript', 'typescript', 'rust', 'python']
      }]
    ],
    syntaxHighlight: false // Disable default highlighting
  }
});

🔧 Usage with Next.js

// next.config.js
import remarkShikiHighlight from 'remark-shiki-highlight-api';

const nextConfig = {
  // For MDX
  pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
  remarkPlugins: [
    [remarkShikiHighlight, {
      theme: 'github-dark'
    }]
  ]
};

export default nextConfig;

⚙️ Configuration Options

interface PluginOptions {
  // Shiki theme to use
  theme?: string | ShikiTheme;

  // Languages to load (loads all by default)
  langs?: string[];

  // Custom class for code blocks
  className?: string;

  // Enable line numbers
  lineNumbers?: boolean;
}

Example with All Options

[remarkShikiHighlight, {
  theme: 'nord',
  langs: ['javascript', 'typescript', 'rust', 'go'],
  className: 'code-block',
  lineNumbers: true
}]

🎨 Styling Your Code

The plugin generates semantic highlight names you can style with CSS:

/* Base code block styles */
code {
  font-family: 'Fira Code', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
}

/* Token highlighting */
::highlight(token-keyword) {
  color: var(--shiki-keyword);
  font-weight: 600;
}

::highlight(token-string) {
  color: var(--shiki-string);
}

::highlight(token-function) {
  color: var(--shiki-function);
}

::highlight(token-comment) {
  color: var(--shiki-comment);
  font-style: italic;
  opacity: 0.7;
}

::highlight(token-variable) {
  color: var(--shiki-variable);
}

::highlight(token-constant) {
  color: var(--shiki-constant);
}

🌈 Theme Support

Works with all Shiki themes out of the box:

// Popular themes
theme: 'github-dark'
theme: 'github-light'
theme: 'nord'
theme: 'dracula'
theme: 'monokai'
theme: 'one-dark-pro'
theme: 'solarized-dark'
theme: 'solarized-light'

Or use a custom theme object:

import myTheme from './my-custom-theme.json';

[remarkShikiHighlight, {
  theme: myTheme
}]

📊 Performance Benefits

Real-world comparison on a technical blog post with 10 code blocks:

Traditional span-based highlighting:

  • DOM nodes: ~4,500
  • HTML size: 180KB
  • Initial render: 85ms

CSS Highlights API (this plugin):

  • DOM nodes: ~350
  • HTML size: 45KB
  • Initial render: 12ms

Result: 92% fewer DOM nodes, 75% smaller HTML, 85% faster rendering.

🔗 How It Works

  1. Parse phase - Remark identifies code blocks in your Markdown
  2. Tokenize - Shiki analyzes the code using TextMate grammars
  3. Transform - Plugin generates clean HTML with data attributes
  4. Hydrate - Client-side script applies CSS Highlights API
  5. Render - Browser displays styled code using native highlighting

No massive span trees. No inline styles. Just clean HTML and performant highlighting.

🌐 Browser Support

The CSS Highlights API is supported in:

  • Chrome/Edge 105+
  • Safari 17.2+
  • Firefox 134+ (behind flag, full support coming soon)

Graceful degradation: Unsupported browsers display unstyled but readable code.

🔌 Integration Examples

Astro with Dark Mode

---
// BlogPost.astro
import BaseLayout from './BaseLayout.astro';
const { frontmatter, Content } = Astro.props;
---

<BaseLayout>
  <article data-theme={frontmatter.theme || 'dark'}>
    <Content />
  </article>
</BaseLayout>

<style>
  [data-theme="dark"] ::highlight(token-keyword) {
    color: #ff79c6;
  }

  [data-theme="light"] ::highlight(token-keyword) {
    color: #d73a49;
  }
</style>

Next.js MDX Component

// CodeBlock.tsx
import { ReactNode } from 'react';

export function CodeBlock({ children }: { children: ReactNode }) {
  return (
    <div className="code-wrapper">
      <pre><code>{children}</code></pre>
    </div>
  );
}

🛠️ Advanced Usage

Custom Language Aliases

[remarkShikiHighlight, {
  theme: 'github-dark',
  langAliases: {
    'js': 'javascript',
    'ts': 'typescript',
    'asm': 'assembly'
  }
}]

Loading Specific Languages

For faster builds, only load languages you actually use:

[remarkShikiHighlight, {
  theme: 'github-dark',
  langs: ['javascript', 'typescript', 'rust']
  // Reduces bundle size by ~70%
}]

Multiple Themes

[remarkShikiHighlight, {
  themes: {
    light: 'github-light',
    dark: 'github-dark'
  }
}]

📚 Real-World Usage

This plugin powers syntax highlighting on:

  • Code Like It’s 198x - Retro programming tutorials
  • This very website - All code examples on stevehill.xyz

🔮 Roadmap

Planned features:

  • Line highlighting - Emphasize specific lines
  • Diff support - Show additions/deletions
  • Copy button - One-click code copying
  • Line numbers - Optional line numbering
  • File names - Display source file names
  • Folding - Collapse long code blocks

🧩 Ecosystem

Part of the shiki-highlight-api family:

  • shiki-highlight-api - Core library
  • remark-shiki-highlight-api - This plugin for Remark/MDX
  • Future: rehype plugin, standalone web component

📖 Documentation

Complete API reference, examples, and migration guides available on:

🎓 Why CSS Highlights API?

Inspired by Pavi’s blog post, the CSS Highlights API represents a fundamental shift in how we think about text styling on the web.

Instead of treating styled text as a hierarchy of elements (the DOM way), we treat it as ranges of text with associated styles (the native browser way). This matches how browsers actually render text internally, resulting in massive performance gains.

🤝 Contributing

Open source and accepting contributions! See the GitHub repo for:

  • Issue templates
  • Contribution guidelines
  • Development setup
  • Testing instructions

📄 License

MIT - Use freely in personal and commercial projects.