React Refractor - Syntax Highlighter
react-refractor is a lightweight React component for syntax highlighting code snippets, acting as a thin wrapper around the `refractor` library. `refractor` itself is a virtual DOM implementation of `Prism.js`, allowing for efficient updates and server-side rendering without direct DOM manipulation. The current stable version is v4.0.0, which dropped Node.js 18 support and upgraded to `refractor` v5. The library maintains a moderately active release cadence, with several minor and major versions released within the last year. A key differentiator is its VDOM-based approach, which makes it performant and flexible for React environments but also means it's incompatible with `Prism.js` plugins. Developers must explicitly import and register specific language syntaxes from `refractor` to keep bundle sizes small, and styling is left to the developer, often by importing `Prism.js` themes. It requires React 18+ and is ESM-only since v3.0.0.
Common errors
-
Error: require() of ES Module node_modules/react-refractor/index.js from ... not supported.
cause Attempting to import `react-refractor` using CommonJS `require()` syntax in a Node.js or older environment after v3.0.0.fixRefactor your imports to use ES Modules syntax: `import { Refractor } from 'react-refractor';`. Ensure your project's `package.json` has `"type": "module"` or your build system handles ESM correctly. -
TypeError: (0 , react_refractor__WEBPACK_IMPORTED_MODULE_2__.Refractor) is not a function
cause Using a default import (`import Refractor from 'react-refractor'`) when `react-refractor` has switched to named exports since v3.0.0.fixChange your import statement to use named exports: `import { Refractor } from 'react-refractor';`. -
Error: No language registered for "javascript" (or any other language name)
cause The specific language grammar (e.g., 'javascript') was not imported from `refractor/lang/` and registered with `registerLanguage()` before being used by the `Refractor` component.fixImport the required language module (e.g., `import js from 'refractor/lang/javascript';`) and then register it: `registerLanguage(js);`.
Warnings
- breaking Version 4.0.0 drops support for Node.js versions 18 and below, requiring Node.js 20 or higher. It also upgrades the underlying `refractor` dependency to v5.0.0.
- breaking Since v3.0.0, `react-refractor` is an ESM-only module, meaning it cannot be imported using CommonJS `require()` statements. All exports are named exports, so default imports are no longer supported.
- breaking Version 3.0.0 and above explicitly require React 18 or higher. It also dropped ES5 compatibility, requiring an ES6-compatible environment.
- gotcha Due to `react-refractor`'s VDOM-based approach, which differs from `Prism.js`'s direct DOM manipulation, you cannot use existing `Prism.js` plugins. This is a fundamental architectural difference.
- gotcha The library does not provide any default styling. You are responsible for importing a compatible stylesheet, typically a Prism.js theme, to make the highlighted code visible and aesthetically pleasing.
Install
-
npm install react-refractor -
yarn add react-refractor -
pnpm add react-refractor
Imports
- Refractor
import Refractor from 'react-refractor'
import { Refractor } from 'react-refractor' - registerLanguage
const { registerLanguage } = require('react-refractor')import { registerLanguage } from 'react-refractor' - Language modules (e.g., javascript)
import { javascript } from 'refractor'import js from 'refractor/lang/javascript'
Quickstart
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Refractor, registerLanguage } from 'react-refractor';
// Import desired languages from 'refractor' and register them
import js from 'refractor/lang/javascript';
import php from 'refractor/lang/php';
import css from 'refractor/lang/css';
registerLanguage(js);
registerLanguage(php);
registerLanguage(css);
// A simple PrismJS theme can be included for basic styling
// This would typically be imported from a CSS file like: import 'prismjs/themes/prism-dark.css';
// For demonstration, we'll just show the component usage.
function App() {
const jsCode = `
const greet = (name) => {
console.log('Hello, ' + name + '!');
};
greet('World');
`;
const phpCode = `
<?php
$name = "PHP";
echo "Hello, " . $name . "!";
?>
`;
return (
<div>
<h2>JavaScript Example</h2>
<Refractor language="javascript" value={jsCode} />
<h2>PHP Example</h2>
<Refractor language="php" value={phpCode} />
<p>Note: Stylesheets are not automatically handled; apply your own Prism.js-compatible theme.</p>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root') || document.createElement('div'));
root.render(<App />);