refractor

repository·main·Indexed 21 days ago

https://github.com/wooorm/refractor

A lightweight virtual syntax highlighter that wraps Prism to output syntax trees (hast) instead of HTML strings. Version 5.0.0. Designed for use with virtual DOM frameworks like React, Preact, or AST-based tools like rehype. It provides three entry points: /core (no languages), the default (36 common languages), and /all (297 supported languages). Supports Node.js 16+, Deno, and modern browsers.

Tokens
3.6K
Snippets
20
Records
24
Agent score
74%

What's inside refractor

  1. Understand refractor entry points

    main

    Refractor provides three different entry points to balance feature set and bundle size. Choosing the right one depends on how many programming languages you need to support:

    • refractor/all: Includes all 297 supported languages. Largest bundle size (~211 kB gzipped).
    • refractor (default): Includes 36 common languages. Medium bundle size (~40 kB gzipped).
    • refractor/core: Includes 0 languages. Smallest bundle size (~12.7 kB gzipped). Use this if you want to manually register only the specific languages you need using refractor.register().
  2. Manage syntax availability and imports

    main

    Refractor provides different entry points depending on your needs for syntax (language) support:

    • refractor/core: Contains the core logic but no syntaxes are included. Use this if you want to minimize bundle size and manually add only the languages you need.
    • refractor: Includes a set of checked syntaxes (verified to work).
    • refractor/all: Includes unchecked syntaxes (all available syntaxes, including those currently being verified).

    You can also manually add more languages to refractor/core or refractor as needed.

    Note on Prism: Prism operates as a singleton. Once you register a language in one place, it becomes available everywhere in your application.

  3. Check compatibility and limitations

    main

    Runtimes

    • Node.js: Compatible with all maintained versions (Node.js 16+).
    • Deno: Supported.
    • Browsers: Supported in modern browsers.

    Limitations

    • Syntaxes: Only custom built syntaxes located in refractor/* will work. Prism's own built-in syntaxes are not importable because they rely on global variables.
    • Plugins: refractor does not support Prism plugins, as most Prism plugins are designed to interact with the DOM.
  4. Handle CSS for syntax highlighting

    main

    refractor does not inject CSS for the syntax highlighted code. Because refractor can run in environments other than the browser (like Node.js), it does not bundle styles.

    If you are using refractor in a browser, you must provide a Prism theme manually. You can use any Prism theme, such as prism-dark from esm.sh.

    <link rel="stylesheet" href="https://esm.sh/prismjs@1.30.0/themes/prism-dark.css">
  5. Use refractor for syntax highlighting

    main

    Refractor wraps Prism to output a syntax tree (AST) instead of an HTML string. This is ideal for rendering in virtual DOM frameworks (React, Preact), CLI environments (via ANSI), or when working with ASTs like rehype.

    import {refractor} from 'refractor'
    
    const tree = refractor.highlight('"use strict";', 'js')
    console.log(tree)
  6. Install refractor

    main

    Refractor is an ESM-only package. Choose the installation method based on your environment:

    Node.js (version 16+)

    Use npm to install the package.

    Deno

    Import directly from esm.sh.

    Browsers

    Import via a module script using esm.sh with the ?bundle query parameter.

    npm install refractor
    // Deno
    import {refractor} from 'https://esm.sh/refractor@5'
    <!-- Browser -->
    <script type="module">
      import {refractor} from 'https://esm.sh/refractor@5?bundle'
    </script>
  7. Use the refractor version with all languages

    main

    The lib/all.js entry point provides a pre-configured instance of refractor that has all 297 supported languages automatically registered. This is the easiest way to use the library if you need broad language support without manually importing and registering each individual language syntax.

    import { refractor } from 'refractor'
    
    // refractor is already configured with all languages
    const syntax = refractor.refractor.register(someLanguage)
  8. Use the refractor package with common languages

    main

    The refractor entry point in this module provides a pre-configured instance of the refractor engine that includes 36 common programming languages out of the box. You can import refractor directly to start highlighting code without manually registering individual language grammars.

    import { refractor } from 'refractor'
    
    // The 'refractor' instance here already has common languages registered
    // and is ready for use.
  9. Serialize refractor output to HTML

    main

    Since refractor returns a hast tree, you can use hast-util-to-html to convert the syntax tree into a serialized HTML string.

    import {toHtml} from 'hast-util-to-html'
    import {refractor} from 'refractor'
    
    const tree = refractor.highlight('"use strict";', 'js')
    console.log(toHtml(tree))
  10. Convert refractor output to React nodes

    main

    You can transform the hast tree returned by refractor into React (or Preact) nodes using hast-util-to-jsx-runtime.

    import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
    import {Fragment, jsxs, jsx} from 'react/jsx-runtime'
    import {refractor} from 'refractor'
    
    const tree = refractor.highlight('"use strict";', 'js')
    const reactNode = toJsxRuntime(tree, {Fragment, jsxs, jsx})
    
    console.log(reactNode)
  11. refractor.highlight(value, language)

    main

    Highlights the provided code string as the specified language. Returns a Root node representing the highlighted code in a tree structure (hast).

    import css from 'refractor/css'
    import {refractor} from 'refractor/core'
    
    refractor.register(css)
    console.log(refractor.highlight('em { color: red }', 'css'))
  12. refractor.alias(name, alias)

    main

    Registers aliases for languages that are already registered. This allows you to use alternative names to trigger the same highlighting logic.

    import markdown from 'refractor/markdown'
    import {refractor} from 'refractor/core'
    
    refractor.register(markdown)
    
    // Register multiple aliases at once
    refractor.alias({markdown: ['mdown', 'mkdn', 'mdwn', 'ron']})
    
    // Now this works instead of throwing an error
    refractor.highlight('*Emphasis*', 'mdown')