React wrapper component for CodeMirror 6 editor with TypeScript support and extensible theming system
—
Built-in themes and utilities for creating custom themes for the CodeMirror editor. The theme system provides light, dark, and no-theme variants out of the box, plus full support for custom theme creation.
Default light theme with clean styling optimized for readability.
/**
* Default light theme extension with white background
* Provides clean, minimal styling for light environments
*/
const defaultLightThemeOption: Extension;Usage Examples:
import CodeMirror from "@uiw/react-codemirror";
import { defaultLightThemeOption } from "@uiw/react-codemirror";
// Using the built-in light theme directly
function LightThemedEditor() {
return (
<CodeMirror
value="// Light theme example"
theme={defaultLightThemeOption}
height="200px"
/>
);
}
// Using string shorthand (equivalent)
function LightThemedEditorShorthand() {
return (
<CodeMirror
value="// Light theme example"
theme="light"
height="200px"
/>
);
}One Dark theme imported from CodeMirror's official theme collection.
/**
* One Dark theme extension (re-exported from @codemirror/theme-one-dark)
* Popular dark theme with purple-blue accent colors
*/
const oneDark: Extension;Usage Examples:
import CodeMirror from "@uiw/react-codemirror";
import { oneDark } from "@uiw/react-codemirror";
// Using the built-in dark theme directly
function DarkThemedEditor() {
return (
<CodeMirror
value="// Dark theme example"
theme={oneDark}
height="200px"
/>
);
}
// Using string shorthand (equivalent)
function DarkThemedEditorShorthand() {
return (
<CodeMirror
value="// Dark theme example"
theme="dark"
height="200px"
/>
);
}Option to disable all built-in theming and use only manually provided theme extensions.
/**
* No theme option - disables all built-in themes
* Use when you want complete control over styling via custom extensions
*/
theme: 'none'Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";
// Using no theme - completely unstyled
function UnstyledEditor() {
return (
<CodeMirror
value="// No built-in theme applied"
theme="none"
height="200px"
/>
);
}
// Using no theme with custom styling
function CustomStyledEditor() {
const customTheme = EditorView.theme({
'&': {
backgroundColor: '#f8f9fa',
color: '#343a40',
},
'.cm-content': {
fontFamily: 'Monaco, monospace',
fontSize: '14px',
},
});
return (
<CodeMirror
value="// Custom styled editor"
theme="none"
extensions={[customTheme]}
height="200px"
/>
);
}Support for creating completely custom themes using CodeMirror's theme system.
Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";
import { javascript } from "@codemirror/lang-javascript";
// Creating a custom theme
function CustomThemedEditor() {
const customTheme = EditorView.theme({
// Editor container
'&': {
color: '#2d3748',
backgroundColor: '#f7fafc',
fontSize: '14px',
fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
},
// Content area
'.cm-content': {
padding: '16px',
minHeight: '100px',
caretColor: '#4299e1',
},
// Cursor and selection
'.cm-cursor, .cm-dropCursor': {
borderLeftColor: '#4299e1',
borderLeftWidth: '2px',
},
'.cm-focused .cm-selectionBackground, ::selection': {
backgroundColor: '#bee3f8',
},
// Line numbers
'.cm-gutters': {
backgroundColor: '#edf2f7',
color: '#a0aec0',
border: 'none',
borderRight: '1px solid #e2e8f0',
},
'.cm-activeLineGutter': {
backgroundColor: '#e2e8f0',
color: '#4a5568',
},
// Active line
'.cm-activeLine': {
backgroundColor: '#f1f5f9',
},
// Matching brackets
'.cm-matchingBracket': {
backgroundColor: '#fed7d7',
outline: '1px solid #fc8181',
},
// Search highlighting
'.cm-searchMatch': {
backgroundColor: '#fef5e7',
outline: '1px solid #f6ad55',
},
'.cm-searchMatch.cm-searchMatch-selected': {
backgroundColor: '#fbd38d',
},
});
return (
<CodeMirror
value={`// Custom themed editor
const greeting = "Hello World!";
console.log(greeting);
function add(a, b) {
return a + b;
}`}
theme={customTheme}
extensions={[javascript()]}
height="250px"
/>
);
}
// Creating a high-contrast theme
function HighContrastEditor() {
const highContrastTheme = EditorView.theme({
'&': {
color: '#000000',
backgroundColor: '#ffffff',
fontSize: '16px',
fontWeight: 'bold',
},
'.cm-content': {
padding: '20px',
caretColor: '#000000',
},
'.cm-cursor': {
borderLeftColor: '#000000',
borderLeftWidth: '3px',
},
'.cm-focused .cm-selectionBackground': {
backgroundColor: '#ffff00',
color: '#000000',
},
'.cm-gutters': {
backgroundColor: '#f0f0f0',
color: '#000000',
borderRight: '2px solid #000000',
fontWeight: 'bold',
},
'.cm-activeLine': {
backgroundColor: '#ffffcc',
},
'.cm-matchingBracket': {
backgroundColor: '#ff0000',
color: '#ffffff',
fontWeight: 'bold',
},
});
return (
<CodeMirror
value="// High contrast theme for accessibility"
theme={highContrastTheme}
height="150px"
/>
);
}Dynamic theme switching functionality for user preferences.
Usage Examples:
import React, { useState } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { oneDark, defaultLightThemeOption } from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";
function ThemeSwitchingEditor() {
const [currentTheme, setCurrentTheme] = useState('light');
const themes = {
light: defaultLightThemeOption,
dark: oneDark,
custom: EditorView.theme({
'&': {
color: '#2d5016',
backgroundColor: '#f0fff4',
},
'.cm-content': {
caretColor: '#22543d',
},
'.cm-focused .cm-selectionBackground': {
backgroundColor: '#c6f6d5',
},
'.cm-gutters': {
backgroundColor: '#e6fffa',
color: '#2d5016',
},
}),
};
return (
<div>
<div style={{ marginBottom: 10 }}>
<label>
Theme:
<select
value={currentTheme}
onChange={(e) => setCurrentTheme(e.target.value)}
style={{ marginLeft: 8 }}
>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="custom">Custom Green</option>
</select>
</label>
</div>
<CodeMirror
value={`// Theme switching demo
// Current theme: ${currentTheme}
const message = "Switch themes using the dropdown above";
console.log(message);`}
theme={themes[currentTheme]}
height="200px"
/>
</div>
);
}
// System theme detection
function SystemThemeEditor() {
const [theme, setTheme] = useState(() => {
// Detect system preference
if (typeof window !== 'undefined') {
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
return 'light';
});
React.useEffect(() => {
if (typeof window !== 'undefined') {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = () => {
setTheme(mediaQuery.matches ? 'dark' : 'light');
};
mediaQuery.addListener(handleChange);
return () => mediaQuery.removeListener(handleChange);
}
}, []);
return (
<div>
<div style={{ marginBottom: 10 }}>
Current theme: {theme} (auto-detected from system)
</div>
<CodeMirror
value="// This editor follows your system theme preference"
theme={theme}
height="150px"
/>
</div>
);
}Extending existing themes with additional styling.
Usage Examples:
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { oneDark } from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";
function ExtendedThemeEditor() {
// Extend the dark theme with custom additions
const extendedDarkTheme = [
oneDark, // Base dark theme
EditorView.theme({
// Additional customizations
'.cm-content': {
fontSize: '16px',
lineHeight: '1.6',
fontFamily: '"Fira Code", monospace',
},
'.cm-gutters': {
fontSize: '14px',
},
// Custom class for highlighted comments
'.cm-comment': {
fontStyle: 'italic',
opacity: '0.8',
},
// Custom scrollbar (webkit browsers)
'.cm-scroller::-webkit-scrollbar': {
width: '8px',
},
'.cm-scroller::-webkit-scrollbar-track': {
background: '#1e1e1e',
},
'.cm-scroller::-webkit-scrollbar-thumb': {
background: '#4a4a4a',
borderRadius: '4px',
},
'.cm-scroller::-webkit-scrollbar-thumb:hover': {
background: '#5a5a5a',
},
}),
];
return (
<CodeMirror
value={`// Extended dark theme with custom font and scrollbar
// This comment should appear italic
const code = "Beautiful syntax highlighting";
console.log(code);`}
theme={extendedDarkTheme}
height="200px"
/>
);
}
// Theme with CSS variables for dynamic customization
function VariableThemeEditor() {
const [primaryColor, setPrimaryColor] = useState('#4299e1');
const variableTheme = EditorView.theme({
'&': {
'--primary-color': primaryColor,
'--primary-light': primaryColor + '20',
'--primary-dark': primaryColor + 'dd',
},
'.cm-content': {
caretColor: 'var(--primary-color)',
},
'.cm-focused .cm-selectionBackground': {
backgroundColor: 'var(--primary-light)',
},
'.cm-cursor': {
borderLeftColor: 'var(--primary-color)',
},
'.cm-activeLine': {
backgroundColor: 'var(--primary-light)',
},
'.cm-matchingBracket': {
backgroundColor: 'var(--primary-dark)',
color: 'white',
},
});
return (
<div>
<div style={{ marginBottom: 10 }}>
<label>
Primary Color:
<input
type="color"
value={primaryColor}
onChange={(e) => setPrimaryColor(e.target.value)}
style={{ marginLeft: 8 }}
/>
</label>
</div>
<CodeMirror
value="// Dynamic theme with CSS variables"
theme={variableTheme}
height="150px"
/>
</div>
);
}Install with Tessl CLI
npx tessl i tessl/npm-uiw--react-codemirror