rehype-prism-plus
Rehype plugin that highlights code blocks with Prism, adding line numbers, line highlighting, and diff annotations to Markdown/MDX output.
Repository Health
Technical Analysis
rehype-prism-plus is a rehype plugin that highlights pre > code blocks with Prism (via the refractor wrapper) inside any unified/rehype/remark processing pipeline, most commonly Markdown-to-HTML and MDX toolchains like xdm, mdx-bundler, and Next.js MDX setups. Beyond plain syntax coloring, it reconstructs each code block into per-line <span> elements so consumers can layer on line numbers, line-range highlighting, and diff-style insert/delete markers directly from code-fence meta strings (e.g. js {1,3-4} showLineNumbers).
It ships three entry points — /common (a small refractor language set), /all (every refractor-supported language), and /generator (bring your own refractor instance with only the languages you register) — letting consumers trade bundle size against language coverage without changing how the plugin is invoked.
What You Get
- Prism-powered syntax highlighting for
pre > codeblocks via refractor, with three entry points (/common,/all,/generator) to control bundle size vs. language coverage - Per-line highlighting driven by code-fence meta syntax like
js {1,3-4}— no extra rehype passes required - Optional line numbers via
showLineNumbers(global, per-language array, or per-block meta flag), including a configurable starting line number - Diff-aware highlighting for
diffanddiff-<language>code blocks that marks added/removed lines ignoreMissinganddefaultLanguageoptions for gracefully handling code blocks with no or unsupported language classes
Common Use Cases
- Next.js/MDX blogs and docs sites - adding syntax-highlighted, line-numbered code samples to MDX content via
@next/mdxormdx-bundler - Static site generators built on unified/rehype - Astro, Gatsby, and custom remark/rehype pipelines that render Markdown to HTML at build time
- Technical documentation with diffs - showing before/after code changes with
diff-js/diff-pythonstyle blocks - Custom language subsets - using
/generatorwith a hand-picked refractor registry to keep highlighting bundles small for a fixed set of supported languages
Under The Hood
Architecture
The package is a single-purpose rehype plugin factory: src/generator.js (323 lines) exports rehypePrismGenerator(refractor), a higher-order function that closes over a caller-supplied refractor instance and returns a standard unified/rehype plugin. Its visitor walks the HAST tree for pre > code elements, extracts the code-fence meta string, runs Prism highlighting via refractor.highlight(), then rebuilds the highlighted output into an array of per-line <span> nodes using a closure (addNodePositionClosure) that assigns unist line/column positions to text and element nodes so a unist-util-filter pass can slice the tree back into one subtree per source line. src/common.js, src/all.js, and src/index.js are thin wrappers that pre-bind the generator to different refractor language registries (a small common set vs. every supported language), giving the library a three-tier entry-point design without duplicating the highlighting logic itself. Because every entry point delegates to the same generator function, any change to the line-reconstruction algorithm propagates uniformly across all three.
Tech Stack
The package is ESM-only (Node 16+), built with microbundle into .es.js output and TypeScript declaration files emitted via tsc -b from JSDoc-annotated plain JavaScript (checkJs, no .ts source). Runtime dependencies are narrowly scoped: refractor (the Prism-in-JS highlighting engine it wraps), unist-util-visit/unist-util-filter/hast-util-to-string for AST traversal, parse-numeric-range for parsing {1,3-4}-style line ranges, and rehype-parse. Dev tooling pairs uvu (a minimal test runner) with eslint/prettier/husky+lint-staged for pre-commit formatting, plus unified/remark/remark-rehype/rehype as integration-test dependencies that exercise the plugin inside real Markdown pipelines rather than in isolation.
Code Quality
A single 491-line test.js using uvu covers the bulk of the option surface — line highlighting, line numbers (including custom starting offsets), diff-block insert/delete classes, and the ignoreMissing/defaultLanguage fallbacks — exercised through both a direct rehype() pipeline and a full remark-rehype pipeline helper. A GitHub Actions workflow (unit.yml) runs npm ci && npm test on every push/PR to main/master. Type safety is partial: the source is plain JavaScript with JSDoc @typedef/@param annotations rather than actual TypeScript, and a handful of @ts-ignore escapes appear around refractor’s dynamic className handling and highlight() return type. Naming is consistent and the core visitor decomposes cleanly into small pure helpers (calculateLinesToHighlight, calculateStartingLine, createLineNodes), though error handling is limited to plain throw/catch-and-ignore rather than a typed error hierarchy.
API Design
The three-entry-point split (/common, /all, /generator) is a genuinely useful ergonomic choice for a syntax-highlighting plugin — most consumers can .use(rehypePrism) with zero configuration, while bundle-conscious consumers can register only the languages they need via /generator without touching the highlighting logic. Reading highlighting options (line ranges, starting line number, showLineNumbers) directly out of the Markdown code-fence meta string rather than requiring separate plugin configuration per code block is a low-boilerplate design that matches how authors already write fenced code blocks.
Used by 3 apps in this directory
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
GPT Researcher
Productivity · AI Assistants
The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.
Ollama
AI Development · Developer Tools
Run Llama, Gemma, DeepSeek, and other open LLMs on your own machine with one command and an OpenAI-compatible API.