Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
React Codemirror
https://github.com/uiwjs/react-codemirror
Admin
CodeMirror 6 component for React. @codemirror https://uiwjs.github.io/react-codemirror/
Tokens:
59,457
Snippets:
404
Trust Score:
9.9
Update:
3 months ago
Context
Skills
Chat
Benchmark
66.3
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# React CodeMirror React CodeMirror is a comprehensive React component library for CodeMirror 6, providing a modern code editor with syntax highlighting, theming, and extensive customization options. Built with TypeScript and React hooks, it offers seamless integration with React applications while maintaining the full power of CodeMirror 6's extensibility. The library includes a rich ecosystem of pre-built themes, language support, and extensions for common editor features. This library simplifies CodeMirror 6 integration by providing React-friendly APIs, automatic state management, and a collection of ready-to-use extensions. It supports controlled and uncontrolled component patterns, custom themes, merge views for diff visualization, and a flexible extension system. The package is designed for modern React applications (16.8+) with full TypeScript support and includes utilities for editor state serialization, event handling, and DOM manipulation. ## Core Component ### Basic CodeMirror Editor ```jsx import React from 'react'; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; function App() { const [value, setValue] = React.useState("console.log('hello world!');"); const onChange = React.useCallback((val, viewUpdate) => { console.log('val:', val); setValue(val); }, []); return ( <CodeMirror value={value} height="200px" extensions={[javascript({ jsx: true })]} onChange={onChange} /> ); } ``` ### useCodeMirror Hook ```jsx import { useEffect, useMemo, useRef } from 'react'; import { useCodeMirror } from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { const editor = useRef(); const extensions = useMemo(() => [javascript()], []); const { setContainer, view, state } = useCodeMirror({ container: editor.current, extensions, value: "console.log('hello world!');\n\n\n", onChange: (value, viewUpdate) => { console.log('Updated:', value); }, }); useEffect(() => { if (editor.current) { setContainer(editor.current); } }, [editor.current]); return <div ref={editor} />; } ``` ## Theme System ### Using Pre-built Themes ```jsx import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { okaidia } from '@uiw/codemirror-theme-okaidia'; import { dracula } from '@uiw/codemirror-theme-dracula'; import { vscodeDark } from '@uiw/codemirror-theme-vscode'; export default function App() { return ( <CodeMirror value="console.log('hello world!');" height="200px" theme={okaidia} extensions={[javascript({ jsx: true })]} /> ); } ``` ### Creating Custom Themes ```jsx import CodeMirror from '@uiw/react-codemirror'; import { createTheme } from '@uiw/codemirror-themes'; import { javascript } from '@codemirror/lang-javascript'; import { tags as t } from '@lezer/highlight'; const myTheme = createTheme({ theme: 'light', settings: { background: '#ffffff', backgroundImage: '', foreground: '#75baff', caret: '#5d00ff', selection: '#036dd626', selectionMatch: '#036dd626', lineHighlight: '#8a91991a', gutterBackground: '#fff', gutterForeground: '#8a919966', fontFamily: 'Menlo, Monaco, "Courier New", monospace', fontSize: '14px', }, styles: [ { tag: t.comment, color: '#787b8099' }, { tag: t.variableName, color: '#0080ff' }, { tag: [t.string, t.special(t.brace)], color: '#5c6166' }, { tag: t.number, color: '#5c6166' }, { tag: t.bool, color: '#5c6166' }, { tag: t.null, color: '#5c6166' }, { tag: t.keyword, color: '#5c6166' }, { tag: t.operator, color: '#5c6166' }, { tag: t.className, color: '#5c6166' }, { tag: t.definition(t.typeName), color: '#5c6166' }, { tag: t.typeName, color: '#5c6166' }, { tag: t.angleBracket, color: '#5c6166' }, { tag: t.tagName, color: '#5c6166' }, { tag: t.attributeName, color: '#5c6166' }, ], }); export default function App() { return ( <CodeMirror value="console.log('hello world!');" height="200px" theme={myTheme} extensions={[javascript({ jsx: true })]} /> ); } ``` ## Language Support ### JavaScript/TypeScript ```jsx import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { const code = `function greet(name: string): string { return \`Hello, \${name}!\`; } console.log(greet('World'));`; return ( <CodeMirror value={code} height="200px" extensions={[javascript({ jsx: true, typescript: true })]} /> ); } ``` ### Markdown with Syntax Highlighting ```jsx import CodeMirror from '@uiw/react-codemirror'; import { markdown, markdownLanguage } from '@codemirror/lang-markdown'; import { languages } from '@codemirror/language-data'; const code = `## Title \`\`\`jsx function Demo() { return <div>demo</div> } \`\`\` \`\`\`bash npm install @uiw/react-codemirror --save \`\`\` [visit url](https://uiwjs.github.io/react-codemirror/) \`\`\`go package main import "fmt" func main() { fmt.Println("Hello, 世界") } \`\`\` `; export default function App() { return ( <CodeMirror value={code} extensions={[markdown({ base: markdownLanguage, codeLanguages: languages })]} /> ); } ``` ### Legacy Language Support ```jsx import CodeMirror from '@uiw/react-codemirror'; import { StreamLanguage } from '@codemirror/language'; import { go } from '@codemirror/legacy-modes/mode/go'; const goLang = `package main import "fmt" func main() { fmt.Println("Hello, 世界") }`; export default function App() { return ( <CodeMirror value={goLang} height="200px" extensions={[StreamLanguage.define(go)]} /> ); } ``` ## Merge View Component ### Side-by-Side Diff Viewer ```jsx import CodeMirrorMerge from 'react-codemirror-merge'; import { EditorView } from 'codemirror'; import { EditorState } from '@codemirror/state'; const Original = CodeMirrorMerge.Original; const Modified = CodeMirrorMerge.Modified; let doc = `one two three four five`; export const Example = () => { return ( <CodeMirrorMerge> <Original value={doc} /> <Modified value={doc.replace(/t/g, 'T') + '\nSix'} extensions={[ EditorView.editable.of(false), EditorState.readOnly.of(true) ]} /> </CodeMirrorMerge> ); }; ``` ## Extensions ### Basic Setup Configuration ```jsx import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { return ( <CodeMirror value="console.log('hello');" height="200px" extensions={[javascript()]} basicSetup={{ lineNumbers: true, highlightActiveLineGutter: true, highlightSpecialChars: true, history: true, foldGutter: true, drawSelection: true, dropCursor: true, allowMultipleSelections: true, indentOnInput: true, syntaxHighlighting: true, bracketMatching: true, closeBrackets: true, autocompletion: true, rectangularSelection: true, crosshairCursor: false, highlightActiveLine: true, highlightSelectionMatches: true, closeBracketsKeymap: true, defaultKeymap: true, searchKeymap: true, historyKeymap: true, foldKeymap: true, completionKeymap: true, lintKeymap: true, tabSize: 2, }} /> ); } ``` ### Color Picker Extension ```jsx import CodeMirror from '@uiw/react-codemirror'; import { color } from '@uiw/codemirror-extensions-color'; import { css } from '@codemirror/lang-css'; export default function App() { const code = `.container { background-color: #ff5733; color: rgb(255, 255, 255); border: 1px solid rgba(0, 0, 0, 0.5); box-shadow: 0 2px 4px hsl(0deg 100% 50% / 0.1); }`; return ( <CodeMirror value={code} height="200px" extensions={[css(), color]} /> ); } ``` ### Hyperlink Extension ```jsx import CodeMirror from '@uiw/react-codemirror'; import { hyperLink } from '@uiw/codemirror-extensions-hyper-link'; import { markdown } from '@codemirror/lang-markdown'; export default function App() { const code = `# Links Check out https://github.com/uiwjs/react-codemirror Visit https://codemirror.net for documentation FTP example: ftp://example.com/file.txt`; return ( <CodeMirror value={code} height="200px" extensions={[markdown(), hyperLink]} /> ); } ``` ### DOM Events Extension ```jsx import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { scroll, content, dom } from '@uiw/codemirror-extensions-events'; export default function App() { return ( <CodeMirror value="console.log('hello');" height="200px" extensions={[ javascript(), scroll({ scroll: (event) => { console.log('Scrolled:', event); }, }), content({ focus: (event) => { console.log('Content focused'); }, blur: (event) => { console.log('Content blurred'); }, }), dom({ mouseenter: (event) => { console.log('Mouse entered editor'); }, mouseleave: (event) => { console.log('Mouse left editor'); }, }), ]} /> ); } ``` ### Mentions Extension ```jsx import CodeMirror from '@uiw/react-codemirror'; import { mentions } from '@uiw/codemirror-extensions-mentions'; export default function App() { const mentionsList = [ { label: '@alice', type: 'text' }, { label: '@bob', type: 'text' }, { label: '@charlie', type: 'text' }, { label: '@david', type: 'text' }, ]; return ( <CodeMirror value="Type @ to trigger mentions" height="200px" extensions={[mentions(mentionsList)]} /> ); } ``` ### Zebra Stripes Extension ```jsx import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { zebraStripes } from '@uiw/codemirror-extensions-zebra-stripes'; const code = `function example() { console.log('Line 1'); console.log('Line 2'); console.log('Line 3'); console.log('Line 4'); console.log('Line 5'); console.log('Line 6'); console.log('Line 7'); console.log('Line 8'); }`; export default function App() { return ( <CodeMirror value={code} height="200px" extensions={[ javascript(), zebraStripes({ step: 2, lightColor: '#eef6ff', darkColor: '#3a404d' }) ]} /> ); } ``` ## Advanced Features ### State Persistence with LocalStorage ```jsx import CodeMirror from '@uiw/react-codemirror'; import { historyField } from '@codemirror/commands'; import { javascript } from '@codemirror/lang-javascript'; const stateFields = { history: historyField }; export function EditorWithPersistence() { const serializedState = localStorage.getItem('myEditorState'); const value = localStorage.getItem('myValue') || ''; return ( <CodeMirror value={value} height="200px" extensions={[javascript()]} initialState={ serializedState ? { json: JSON.parse(serializedState || ''), fields: stateFields, } : undefined } onChange={(value, viewUpdate) => { localStorage.setItem('myValue', value); const state = viewUpdate.state.toJSON(stateFields); localStorage.setItem('myEditorState', JSON.stringify(state)); }} /> ); } ``` ### Editor with Ref Access ```jsx import React, { useRef, useEffect } from 'react'; import CodeMirror, { ReactCodeMirrorRef } from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { const editorRef = useRef<ReactCodeMirrorRef>(null); const insertText = () => { if (editorRef.current && editorRef.current.view) { const view = editorRef.current.view; const transaction = view.state.update({ changes: { from: view.state.doc.length, insert: '\n// Added via ref' }, }); view.dispatch(transaction); } }; useEffect(() => { if (editorRef.current) { console.log('Editor element:', editorRef.current.editor); console.log('Editor state:', editorRef.current.state); console.log('Editor view:', editorRef.current.view); } }, []); return ( <div> <CodeMirror ref={editorRef} value="console.log('hello');" height="200px" extensions={[javascript()]} /> <button onClick={insertText}>Insert Text</button> </div> ); } ``` ### Read-only and Editable States ```jsx import React, { useState } from 'react'; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { const [readOnly, setReadOnly] = useState(false); return ( <div> <button onClick={() => setReadOnly(!readOnly)}> Toggle Read-Only </button> <CodeMirror value="console.log('hello world!');" height="200px" extensions={[javascript()]} readOnly={readOnly} editable={!readOnly} /> </div> ); } ``` ### Editor Statistics and Callbacks ```jsx import React, { useState } from 'react'; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; export default function App() { const [stats, setStats] = useState(null); const onStatistics = (data) => { setStats(data); }; const onCreateEditor = (view, state) => { console.log('Editor created:', { view, state }); }; return ( <div> <CodeMirror value="console.log('hello');\nconst x = 42;" height="200px" extensions={[javascript()]} onStatistics={onStatistics} onCreateEditor={onCreateEditor} onChange={(value, viewUpdate) => { console.log('Changed:', value); }} /> {stats && ( <div> <p>Lines: {stats.lineCount}</p> <p>Length: {stats.length}</p> <p>Selected: {stats.selectedText ? 'Yes' : 'No'}</p> <p>Selection: {stats.selectionCode}</p> </div> )} </div> ); } ``` ## Summary React CodeMirror provides a production-ready code editor solution for React applications with minimal setup. The library excels in common scenarios like code playgrounds, documentation sites, configuration editors, and IDE-like interfaces. Its pre-built themes, language support for 50+ programming languages, and battle-tested extensions make it suitable for everything from simple syntax highlighting to complex multi-pane editing experiences. The component is highly performant with lazy loading, automatic state reconciliation, and optimized re-rendering. Integration patterns follow standard React conventions with controlled/uncontrolled components, refs for imperative access, and hooks for advanced customization. The merge view component enables git-style diff visualization, while the extension system allows deep integration with CodeMirror's plugin ecosystem. State serialization enables features like undo/redo persistence, draft saving, and collaborative editing foundations. The library works seamlessly with React frameworks (Next.js, Remix, Vite) and includes TypeScript definitions for type-safe development.