rehype-prism-plus

Rehype plugin that highlights code blocks with Prism, adding line numbers, line highlighting, and diff annotations to Markdown/MDX output.

Library
npm
v2.0.2
201stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
38/100Needs Attention
Development Activity4
Maintenance32
Community40
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture75
Code Quality65
Innovation75
Learning Curve55

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 > code blocks 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 diff and diff-<language> code blocks that marks added/removed lines
  • ignoreMissing and defaultLanguage options 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/mdx or mdx-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-python style blocks
  • Custom language subsets - using /generator with 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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search