React component library for syntax highlighting with highlight.js and Prism.js support.
—
Enhanced syntax highlighting using Prism.js through the refractor AST parser. Prism.js offers extended language support including modern web technologies like JSX, TSX, and improved highlighting for various programming languages.
Full Prism.js build with comprehensive language support and default Prism styling.
/**
* React syntax highlighter component using Prism.js (refractor)
*/
const Prism: SyntaxHighlighterComponent & {
/** Array of supported language identifiers */
supportedLanguages: string[];
};
type SyntaxHighlighterComponent = React.ComponentType<SyntaxHighlighterProps>;Usage Examples:
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';
// JSX highlighting (Prism.js specialty)
const JSXExample = () => {
const jsxCode = `import React, { useState } from 'react';
const Counter = ({ initialCount = 0 }) => {
const [count, setCount] = useState(initialCount);
return (
<div className="counter">
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
</div>
);
};
export default Counter;`;
return (
<SyntaxHighlighter language="jsx" style={dark}>
{jsxCode}
</SyntaxHighlighter>
);
};
// TypeScript highlighting
const TypeScriptExample = () => {
const tsCode = `interface User {
id: number;
name: string;
email: string;
profile?: UserProfile;
}
interface UserProfile {
avatar: string;
bio: string;
location?: string;
}
class UserService {
private users: Map<number, User> = new Map();
async createUser(userData: Omit<User, 'id'>): Promise<User> {
const id = Math.max(...this.users.keys()) + 1;
const user: User = { id, ...userData };
this.users.set(id, user);
return user;
}
getUserById(id: number): User | undefined {
return this.users.get(id);
}
}`;
return (
<SyntaxHighlighter language="typescript" style={dark}>
{tsCode}
</SyntaxHighlighter>
);
};Light Prism.js build requiring manual language registration.
/**
* Light Prism.js syntax highlighter requiring manual language registration
*/
const PrismLight: SyntaxHighlighterComponent & {
/** Register a Prism language definition */
registerLanguage: (name: string, language: any) => void;
/** Create language aliases for existing registered languages */
alias: (name: string, aliases: string | string[]) => void;
};Usage Examples:
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import jsx from 'react-syntax-highlighter/dist/esm/languages/prism/jsx';
import typescript from 'react-syntax-highlighter/dist/esm/languages/prism/typescript';
import prism from 'react-syntax-highlighter/dist/esm/styles/prism/prism';
// Register required languages
SyntaxHighlighter.registerLanguage('jsx', jsx);
SyntaxHighlighter.registerLanguage('typescript', typescript);
// Create language aliases
SyntaxHighlighter.alias('typescript', ['ts']);
SyntaxHighlighter.alias('jsx', ['react']);
const PrismLightExample = () => {
return (
<SyntaxHighlighter language="jsx" style={prism}>
{jsxCode}
</SyntaxHighlighter>
);
};Prism.js provides superior support for modern web technologies and markup languages.
// Vue.js Single File Components
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism';
const VueExample = () => {
const vueCode = `<template>
<div class="user-profile">
<h2>{{ user.name }}</h2>
<img :src="user.avatar" :alt="user.name" />
<p v-if="user.bio">{{ user.bio }}</p>
<button @click="followUser">Follow</button>
</div>
</template>
<script>
export default {
name: 'UserProfile',
props: {
user: {
type: Object,
required: true
}
},
methods: {
followUser() {
this.$emit('follow', this.user.id);
}
}
}
</script>
<style scoped>
.user-profile {
border: 1px solid #ccc;
border-radius: 8px;
padding: 16px;
}
</style>`;
return (
<SyntaxHighlighter language="vue" style={tomorrow}>
{vueCode}
</SyntaxHighlighter>
);
};
// GraphQL Schema
const GraphQLExample = () => {
const graphqlCode = `type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
publishedAt: DateTime
}
type Query {
users(first: Int, after: String): UserConnection!
user(id: ID!): User
posts(authorId: ID, published: Boolean): [Post!]!
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}`;
return (
<SyntaxHighlighter language="graphql" style={tomorrow}>
{graphqlCode}
</SyntaxHighlighter>
);
};Enhanced support for popular web frameworks and their specific syntax.
// Svelte Components
const SvelteExample = () => {
const svelteCode = `<script>
import { onMount } from 'svelte';
let count = 0;
let doubled;
$: doubled = count * 2;
onMount(() => {
console.log('Component mounted');
});
function increment() {
count += 1;
}
</script>
<main>
<h1>Count: {count}</h1>
<p>Doubled: {doubled}</p>
<button on:click={increment}>+</button>
</main>
<style>
main {
text-align: center;
padding: 1em;
}
</style>`;
return (
<SyntaxHighlighter language="svelte" style={tomorrow}>
{svelteCode}
</SyntaxHighlighter>
);
};
// MDX (Markdown + JSX)
const MDXExample = () => {
const mdxCode = `# My Blog Post
This is a regular markdown paragraph.
import { Chart } from './components/Chart';
import { DataTable } from './components/DataTable';
Here's an interactive chart embedded in markdown:
<Chart
data={salesData}
type="line"
title="Monthly Sales"
/>
## Code Examples
Here's some JavaScript:
\`\`\`javascript
const greeting = (name) => {
return \`Hello, \${name}!\`;
};
\`\`\`
And here's a data table:
<DataTable
columns={['Name', 'Age', 'City']}
data={userData}
sortable
/>
## Conclusion
This demonstrates the power of combining Markdown with React components.`;
return (
<SyntaxHighlighter language="mdx" style={tomorrow}>
{mdxCode}
</SyntaxHighlighter>
);
};Prism.js provides better tokenization for specific language features.
// CSS with Advanced Features
const CSSExample = () => {
const cssCode = `/* CSS Custom Properties and Grid */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--font-size-base: 16px;
--border-radius: 8px;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 2rem;
padding: 2rem;
background: linear-gradient(
135deg,
var(--primary-color) 0%,
var(--secondary-color) 100%
);
}
.card {
background: white;
border-radius: var(--border-radius);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
transition: transform 0.2s ease-in-out;
}
.card:hover {
transform: translateY(-2px);
}
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
padding: 1rem;
}
}`;
return (
<SyntaxHighlighter language="css" style={tomorrow}>
{cssCode}
</SyntaxHighlighter>
);
};
// Rust with Advanced Features
const RustExample = () => {
const rustCode = `use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct User {
id: u64,
name: String,
email: String,
age: Option<u8>,
}
#[derive(Debug)]
enum DatabaseError {
ConnectionFailed,
QueryFailed(String),
UserNotFound(u64),
}
impl std::fmt::Display for DatabaseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DatabaseError::ConnectionFailed => write!(f, "Database connection failed"),
DatabaseError::QueryFailed(query) => write!(f, "Query failed: {}", query),
DatabaseError::UserNotFound(id) => write!(f, "User with id {} not found", id),
}
}
}
struct UserRepository {
users: HashMap<u64, User>,
}
impl UserRepository {
fn new() -> Self {
Self {
users: HashMap::new(),
}
}
fn create_user(&mut self, user: User) -> Result<u64, DatabaseError> {
let id = user.id;
self.users.insert(id, user);
Ok(id)
}
fn get_user(&self, id: u64) -> Result<&User, DatabaseError> {
self.users.get(&id).ok_or(DatabaseError::UserNotFound(id))
}
}`;
return (
<SyntaxHighlighter language="rust" style={tomorrow}>
{rustCode}
</SyntaxHighlighter>
);
};Understanding when to choose Prism.js over highlight.js.
// Prism.js advantages:
// ✓ Better JSX/TSX support
// ✓ More modern web framework support (Vue, Svelte, etc.)
// ✓ Better CSS highlighting with modern features
// ✓ Enhanced markup language support (MDX, etc.)
// ✓ More granular tokenization
// ✓ Better plugin ecosystem
// Highlight.js advantages:
// ✓ Auto-detection of languages
// ✓ Smaller core size
// ✓ More language coverage overall
// ✓ Better performance for large code blocks
// Migration from highlight.js to Prism
// Before (highlight.js)
import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
// After (Prism.js)
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { prism } from 'react-syntax-highlighter/dist/esm/styles/prism';
// Component usage remains the same
<SyntaxHighlighter language="jsx" style={prism}>
{code}
</SyntaxHighlighter>Adding custom language support to Prism.js builds.
// Example: Adding custom templating language
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
// Define custom language grammar
const customTemplate = {
'template-tag': {
pattern: /\{\{[\s\S]*?\}\}/,
inside: {
'delimiter': {
pattern: /^\{\{|\}\}$/,
alias: 'punctuation'
},
'variable': /\b\w+\b/
}
},
'string': /"(?:[^"\\]|\\.)*"/,
'number': /\b\d+(?:\.\d+)?\b/,
'operator': /[=<>!]=?|[&|]{2}|\+\+?|--?/,
'punctuation': /[{}[\];(),.:]/
};
// Register the custom language
SyntaxHighlighter.registerLanguage('custom-template', customTemplate);
// Usage
const CustomTemplateExample = () => {
const templateCode = `<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>Welcome, {{user.name}}!</h1>
{{#if user.isAdmin}}
<div class="admin-panel">
<a href="/admin">Admin Dashboard</a>
</div>
{{/if}}
<ul>
{{#each posts}}
<li>
<h2>{{title}}</h2>
<p>{{excerpt}}</p>
<small>By {{author}} on {{date}}</small>
</li>
{{/each}}
</ul>
</body>
</html>`;
return (
<SyntaxHighlighter language="custom-template" style={prism}>
{templateCode}
</SyntaxHighlighter>
);
};// Choose Prism.js for:
const modernWebProjects = {
frameworks: ['React', 'Vue', 'Svelte', 'Angular'],
languages: ['JSX', 'TSX', 'Vue SFC', 'Svelte'],
features: ['Modern CSS', 'GraphQL', 'MDX', 'Template literals']
};
// Choose highlight.js for:
const traditionalProjects = {
features: ['Auto-detection', 'Large code blocks', 'Performance-critical'],
languages: ['General programming', 'Server-side languages', 'Legacy syntax']
};
// Hybrid approach: Use both based on content type
const LanguageSelector = ({ language, children }) => {
const prismLanguages = ['jsx', 'tsx', 'vue', 'svelte', 'graphql', 'mdx'];
const usePrism = prismLanguages.includes(language);
if (usePrism) {
return (
<PrismSyntaxHighlighter language={language} style={prismStyle}>
{children}
</PrismSyntaxHighlighter>
);
}
return (
<HljsSyntaxHighlighter language={language} style={hljsStyle}>
{children}
</HljsSyntaxHighlighter>
);
};Install with Tessl CLI
npx tessl i tessl/npm-react-syntax-highlighter