lexical icon indicating copy to clipboard operation
lexical copied to clipboard

Migrate lexical-code from PrismJS to Shiki

Open ivailop7 opened this issue 1 year ago • 8 comments

PrismJS appears to be no longer maintained and Shiki seems to be the closest maintained alternative for syntax highlighting. A number of people have suggested the migration and I agree it makes sense, primarily because PrismJS is not ESM and creates issues when used with certain server-side rendering frameworks.

ivailop7 avatar Aug 29 '24 20:08 ivailop7

I have looked into this a little bit, the downsides are:

  • Shiki is larger since it brings in a wasm build of the oniguruma regex engine (~500kb gzip I think) required to support the TextMate grammars that all of the syntax highlighting is defined with https://shiki.style/guide/bundles
  • It's designed more for ahead-of-time highlighting rather than as-you-type highlighting
  • It uses inline style rather than semantic classes

Probably not a deal-breaker for everyone but I assume that there are many people that would prefer the dead-end prismjs solution at <100kb

etrepum avatar Aug 29 '24 20:08 etrepum

Not tied to the framework, but it appears everyone I've spoken to recently is switching to this one, short of Monaco and CodeMirror embeds. Size-wise - yes, 5x increase is significant. If there are other reasonable alternatives, I'm all ears.

ivailop7 avatar Aug 29 '24 20:08 ivailop7

I didn't find anything better, which was disappointing. Maybe the ideal would be to properly divorce highlighting from the code node model so that either solution (or something bespoke, e.g. a custom treesitter based highlighter) could be used. For the most part it really is just a display concern, shouldn't need such tight coupling.

etrepum avatar Aug 29 '24 22:08 etrepum

Looks like https://github.com/wooorm/starry-night is a similar project to shiki but AST and class based

etrepum avatar Aug 30 '24 01:08 etrepum

Looks like the size concerns with Shiki are being addressed https://github.com/shikijs/shiki/pull/761

etrepum avatar Aug 31 '24 05:08 etrepum

Also - could the list of languages be made pluggable? If I want to support a different subset of prism langauges than the existing lexical-code package, I have to fork or patch the list of languages. Would be awesome if I could customize that without the fork/patch.

rockwotj avatar Sep 23 '24 15:09 rockwotj

Given that everything in prism is global you should be able to add languages by importing them before you import lexical code. Removing them is a bit trickier but you could configure your bundler to make some of them return an empty module or to eliminate those imports altogether.

etrepum avatar Sep 23 '24 15:09 etrepum

Also, I've had to import Prism like so:

import Prism from "prismjs"; if (typeof globalThis.Prism === 'undefined') { globalThis.Prism = Prism;}
import {CodeNode} from '@lexical/code';

Otherwise, I was getting an exception at runtime of global variable Prism not available:

  • https://github.com/remix-run/remix/discussions/8182

(I was needing @lexical/code and Prism to have some basic triple-backtick-block rendering in @lexical/markdown, unfortunately currently @lexical/markdown and @lexical/code do not work without installed and global Prism)

vadimkantorov avatar Feb 22 '25 12:02 vadimkantorov

Lexical v0.34.0 comes with experimental Shiki support.

kyoshino avatar Aug 10 '25 23:08 kyoshino

to have some basic triple-backtick-block rendering in @lexical/markdown

Hopefully, triple-backticks in @lexical/markdown can now be rendered without highlighting / depending on @lexical/code too (especially if highlighting adds quite a large payload)

vadimkantorov avatar Aug 11 '25 17:08 vadimkantorov

For compatibility reasons prismjs is included in the bundle whether you use it or not, unless you configure your bundler to eliminate it accordingly. It has always been possible to not enable highlighting.

etrepum avatar Aug 11 '25 17:08 etrepum