markdown-it-highlightjs

Preset that wires highlight.js into markdown-it so fenced, indented, and inline code blocks get syntax-highlighted HTML at render time.

Library
npm
v4.3.0
71stars
Unlicense

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
30/100Needs Attention
Development Activity4
Maintenance0
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
66/100Good
Architecture78
Code Quality82
Innovation58
Learning Curve45

markdown-it-highlightjs is a markdown-it plugin that plugs highlight.js in as the renderer’s options.highlight callback, so every fenced and indented code block gets syntax-highlighted HTML during render instead of requiring a second client-side pass. It ships as two entry points: a zero-config default preset that bundles the full highlight.js language pack and turns on auto-detection, and a core variant that takes a caller-supplied hljs instance so bundlers can tree-shake down to only the languages actually used.

Beyond fenced blocks, the plugin can also add the hljs class to indented code and inline code spans, and supports declaring a language for inline code using either Pandoc (`x=4`{.js}) or kramdown (`x=4`{:.js}) attribute syntax, with escaping applied to the resulting class name to avoid leaking markup through it.

What You Get

  • A core plugin that highlights fenced code blocks using a caller-provided highlight.js instance, so bundlers only ship the languages you actually register
  • A zero-config default export that pre-loads the full highlight.js language pack and enables automatic language detection out of the box
  • Support for tagging indented (non-fenced) code blocks and inline code spans with the hljs class alongside fenced blocks
  • Inline code language declarations via Pandoc (`code`{.js}) or kramdown (`code`{:.js}) attribute syntax, with safe HTML-escaping of the resulting class
  • Hooks for registering additional highlight.js languages or language aliases that aren’t included in the standard pack

Common Use Cases

  • Static site generators rendering docs - a docs or blog build pipeline using markdown-it needs fenced code blocks highlighted at build time without a client-side JS highlighter
  • Bundle-size-conscious apps - a browser-side app uses the core entry point with a hand-picked highlight.js/lib/core build plus only the languages it needs, instead of shipping the full highlight.js language pack
  • Content platforms supporting inline code annotations - a CMS or note-taking tool wants writers to tag inline code spans with a language (e.g. `x=4`{.js}) and have them highlighted the same way as fenced blocks
  • Projects with non-standard languages - a team writing docs for an internal DSL or niche language registers a custom highlight.js grammar via register so it highlights like any built-in language

Under The Hood

Architecture The plugin is a thin two-file module (src/core.ts, src/index.ts) built with esbuild to CJS in dist/. core.ts implements the actual markdown-it integration: it patches md.options.highlight with a bound highlight/highlightAuto function, wraps the renderer’s fence (and optionally code_block) rules to inject the hljs class via string replacement on the rendered HTML, and — when inline is enabled — registers a core rule (inline_code_language) before the linkify rule to detect Pandoc/kramdown attribute syntax following inline code tokens and stash the parsed language on token metadata, plus a replaced code_inline renderer that reads it back. index.ts is a small facade that defaults hljs to the full highlight.js pack and forwards to core. There’s no internal service layer or state beyond closures captured at use() time — a fenced-code change ripples only through the wrapped renderer functions, and swapping highlight.js instances only requires passing a different hljs option to core.

Tech Stack Written in TypeScript, compiled to CJS via esbuild for the runtime build and by the TypeScript compiler for declaration files only, with a dedicated linter enforcing style. The single runtime dependency is highlight.js; markdown-it itself is only a peer/type dependency, not bundled. Tests run under Mocha and Chai, with a separate type-import test file used purely to typecheck the published declaration surface before release. The prepack script chains build, lint, typecheck, tests, and the type-import check, gating every publish.

Code Quality The test suite covers both entry points fairly deeply — cases covering the “missing hljs instance” error, class injection, indented-code toggling, auto/no-auto detection, custom language registration and aliasing, all of the inline-highlight formats (Pandoc, kramdown, class escaping, disabled-by-default), and a third-party-plugin interop scenario where another plugin overrides the highlight callback. The core module uses explicit typed interfaces and consistently narrows null/undefined rather than swallowing errors silently; its two try/catch blocks around highlight.js calls deliberately fall back to escaped plain text on illegal syntax, which is documented behavior rather than a hidden failure mode. No coverage tooling is wired up, but the ratio of test cases to the small public surface area is high.

API Design The public API is minimal and consistent: a single .use(plugin, opts) call with a flat options object, sensible defaults for the common case (auto-detection and code-class injection on for the default export, off for core), and one required option (hljs) only on the low-level entry point. Documentation in the README covers every option with a table plus a runnable example, so getting started needs almost no boilerplate beyond installing highlight.js. The two-tier design (convenience default vs. explicit core) is the one place the API asks the consumer to make a real decision, and it’s clearly signposted in the docs.

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