refractor
Lightweight virtual syntax highlighter that wraps Prism to output hast syntax trees instead of HTML strings.
Repository Health
Technical Analysis
Refractor wraps Prism, the widely used browser syntax highlighter, so that highlighting produces a hast (HTML AST) tree instead of a serialized HTML string. That distinction matters for any tool built on virtual DOM diffing (React, Preact) or on unified/rehype content pipelines: instead of dropping dangerouslySetInnerHTML strings into the DOM, callers get a structured tree of element and text nodes they can diff, transform, or serialize themselves.
The package ships three entry points sized for different needs: refractor (36 common languages by default), refractor/core (zero languages, register only what you use), and refractor/all (all 290+ Prism-supported grammars). Because Prism’s own grammar files rely on global state and aren’t independently importable, refractor re-packages every supported grammar as a self-contained function that can be registered against a refractor/core instance, keeping bundle size proportional to the languages actually used.
It is the syntax-highlighting engine underneath several popular downstream packages, including react-syntax-highlighter and rehype-prism-plus, which is why most consumers never call it directly but still depend on its correctness and language coverage.
What You Get
- A
refractor.highlight(value, language)API that returns a hastRootnode instead of an HTML string - Three tiered entry points —
refractor(common languages),refractor/core(bring your own), andrefractor/all(everything) — so bundle size scales with actual language usage - Every Prism grammar re-packaged as an importable, registerable function (
refractor/markdown,refractor/rust, etc.), working around Prism’s normal reliance on global state - Alias support (
refractor.alias) and introspection (refractor.registered,refractor.listLanguages) for managing which languages and shorthand names are active - Full TypeScript types generated via JSDoc +
tsc, with 100% type coverage enforced in CI
Common Use Cases
- Rendering syntax-highlighted code blocks in React or Preact apps without injecting raw HTML strings
- Powering markdown/MDX pipelines built on remark/rehype that need highlighted code as part of the AST, not as a final HTML blob
- Serving as the highlighting engine inside higher-level packages like
react-syntax-highlighterorrehype-prism-plus - Building custom code renderers that target non-HTML output — ANSI terminal colors, PDF, or other tree-consuming serializers
- Selectively bundling only the languages a docs site or editor actually needs via the
refractor/core+refractor/*entry points
Under The Hood
Architecture
The package is organized around a single core module (lib/core.js) that implements a Refractor class wrapping a patched copy of Prism’s tokenizer (lib/prism-core.js), with lib/common.js and lib/all.js acting as pre-configured entry points that import and register subsets of the 290+ per-language files under lang/. Each language file in lang/ is a small function of shape (prism: Refractor) => void that calls prism.languages[...] to register a grammar plus any aliases, decoupling grammar registration from Prism’s normal reliance on browser globals. Highlighting itself walks Prism’s token stream and converts it into hast element/text nodes rather than HTML markup, which is the one architectural change that differentiates this package from vanilla Prism; the script/languages.js and script/list.js build scripts regenerate the lang/ directory and its documentation table from upstream Prism on demand.
Tech Stack
The project is plain ESM JavaScript ("type": "module") with no runtime framework dependency beyond hastscript (hast node construction), parse-entities (HTML entity decoding), and @types/hast/@types/prismjs for typing — prismjs itself is a dev dependency only, vendored and patched via patch-package at build time rather than depended on directly. Type safety comes from TypeScript’s checkJs mode operating directly over JSDoc-annotated .js files (tsc --build) rather than authoring .ts sources, with type-coverage enforcing 100% coverage in CI. Linting and formatting run through xo and prettier, and the whole repo is unified/remark-linted via remark-preset-wooorm, reflecting its place in Titus Wormer’s broader unified/rehype/remark ecosystem.
Code Quality
Tests live under test/index.js and run via Node’s built-in node:test runner against refractor/all, covering the public API (highlight, register, alias, registered, listLanguages) plus per-language fixture comparisons stored in test/fixtures/. Coverage is enforced at 100% via c8 --check-coverage, and the test script chains generation, build, formatting, and coverage gates together, so a change that breaks typing, linting, or coverage fails CI outright. Error handling is explicit and deliberate — invalid value/language arguments throw descriptive TypeError-style messages that are directly asserted against in tests, rather than failing silently.
What Makes It Unique Refractor’s core insight is narrow but valuable: Prism is a mature, widely trusted highlighter, but its output is an HTML string, which is awkward for any tool built on ASTs or virtual DOM diffing. Refractor solves this by re-exporting Prism’s tokenizer output as hast nodes and re-packaging all of Prism’s otherwise-global-dependent grammar files as independently importable functions — without reimplementing Prism’s actual tokenization logic. That combination of AST-native output and per-language tree-shakeable imports is why it became the de facto highlighting layer for the rehype/unified ecosystem and for React-based code renderers, despite not introducing any novel highlighting algorithm itself.
Used by 5 apps in this directory
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
hoodik
File Storage · Security
Self-hosted, end-to-end encrypted cloud storage with browser-based encryption and S3-compatible storage support
Notesnook
Note Taking · File Storage · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Outline
Knowledge Management · Collaboration
A fast, real-time collaborative knowledge base for growing teams built on React, Node.js, and ProseMirror.
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language