Skip to content

fix(rehype-shiki): only import every grammar without a highlighter - #9212

Open
ovflowd wants to merge 1 commit into
mainfrom
fix/rehype-shiki-lazy-highlighter
Open

ovflowd wants to merge 1 commit into
mainfrom
fix/rehype-shiki-lazy-highlighter

Conversation

@ovflowd

@ovflowd ovflowd commented Oct 10, 2026

Copy link
Copy Markdown
Member

Description

This PR makes @node-core/rehype-shiki's plugin import index.mjs only when it has to create a highlighter itself.

plugin.mjs imported index.mjs statically, and that module imports every grammar Shiki bundles (LANGS) as soon as it's loaded. So a caller passing its own highlighter still paid for all of them: importing the plugin loaded 260 grammar modules on every thread that used it. It's now a dynamic import, inside the branch that creates the default highlighter, and a patch changeset releases it.

Validation

  • The package's unit tests (10) pass, and so do lint:js and Prettier.
  • Importing plugin.mjs loads 260 grammar modules before this change and none after it, counted with a module load hook.

Related Issues

Refs: nodejs/doc-kit#1156, which highlights with its own highlighter that loads grammars on demand, and can then use this plugin instead of a copy of it.

Check List

  • I have read the Contributing Guidelines and made commit messages that follow the guideline.
  • I have run pnpm format to ensure the code follows the style guide.
  • I have run pnpm test to check if all tests are passing.
  • I have run pnpm build to check if the website builds without errors.
  • I've covered new added functionality with unit tests if necessary.

@ovflowd
ovflowd requested a review from a team as a code owner October 10, 2026 16:24
Copilot AI balanced review requested due to automatic review settings October 10, 2026 16:24
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nodejs-org Ready Ready Preview Oct 10, 2026 6:01pm UTC

Request Review

@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.15%. Comparing base (bbbdde7) to head (e1c50ce).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9212      +/-   ##
==========================================
+ Coverage   86.07%   86.15%   +0.08%     
==========================================
  Files          86       86              
  Lines        6060     6075      +15     
  Branches      359      360       +1     
==========================================
+ Hits         5216     5234      +18     
+ Misses        840      837       -3     
  Partials        4        4              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The supplied-highlighter path needs an automated regression test proving bundled grammars remain unloaded.

1 open finding
What changed in this PR

Defers loading bundled Shiki grammars when callers provide their own highlighter, reducing import overhead for consumers such as nodejs/doc-kit.

Changes:

  • Dynamically imports the default highlighter only when needed.
  • Adds a patch changeset.
File Description
packages/​rehype-shiki/​src/​plugin.mjs Lazily loads the grammar-heavy default highlighter.
.changeset/​lazy-rehype-shiki-highlighter.md Records the patch release.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/rehype-shiki/src/plugin.mjs
ovflowd added a commit to nodejs/doc-kit that referenced this pull request Oct 10, 2026
The Shiki plugin registered every bundled language (~250 grammars) in
each thread that highlighted code, which cost ~2s and ~100MB per thread
and made every highlight several times slower, as each code block was
matched against grammars it never uses. Importing it also imported all
of them, through `@node-core/rehype-shiki`'s `LANGS` and its plugin,
on every thread loading `jsx-ast`, the main thread included.

The highlighter now registers a bundled language the first time code in
it is highlighted, along with the bundled languages a configured one
embeds, and lists the bundled ones from their metadata alone, without
importing `LANGS`. The themes are given to Shiki by name, which it keeps
parsed instead of parsing them for every highlight. Importing
`@node-core/rehype-shiki`'s plugin still imports every grammar until
nodejs/nodejs.org#9212 is released.

The grammars now come from doc-kit's own `shiki` dependency (4.4.3)
rather than the copy `@node-core/rehype-shiki` pins (4.3.1). Its C++
grammar highlights types and template arguments differently, which
shows on the Node.js docs' C++ examples.

Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

📦 Build Size Comparison

Summary

Metric Value
Old Total First Load JS 7.20 MB
New Total First Load JS 7.20 MB
Delta 0 B (0.00%)

ovflowd added a commit to nodejs/doc-kit that referenced this pull request Oct 10, 2026
The Shiki plugin registered every bundled language (~250 grammars) in
each thread that highlighted code, which cost ~2s and ~100MB per thread
and made every highlight several times slower, as each code block was
matched against grammars it never uses. Importing it also imported all
of them, through `@node-core/rehype-shiki`'s `LANGS` and its plugin,
on every thread loading `jsx-ast`, the main thread included.

The highlighter now registers a bundled language the first time code in
it is highlighted, along with the bundled languages a configured one
embeds, and lists the bundled ones from their metadata alone, without
importing `LANGS`. The themes are given to Shiki by name, which it keeps
parsed instead of parsing them for every highlight. Importing
`@node-core/rehype-shiki`'s plugin still imports every grammar until
nodejs/nodejs.org#9212 is released.

The grammars now come from doc-kit's own `shiki` dependency (4.4.3)
rather than the copy `@node-core/rehype-shiki` pins (4.3.1). Its C++
grammar highlights types and template arguments differently, which
shows on the Node.js docs' C++ examples.

Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
The plugin imported `index.mjs` statically, and that module imports
every grammar Shiki bundles (`LANGS`) as soon as it's loaded, so a
caller passing its own highlighter still paid for all of them: 260
grammar modules on each thread that loads the plugin. It's now imported
only when the plugin has to create a highlighter itself.

This lets doc-kit, which highlights with a highlighter that loads
grammars on demand, use the plugin rather than a copy of it.

Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — e1c50ced Deployed Oct 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants