React components for integrating Microsoft's Monaco Editor into React applications
—
The MonacoEditor component provides full Monaco Editor functionality as a React component, supporting both controlled and uncontrolled modes with complete lifecycle management.
React component wrapper for Monaco Editor with full TypeScript support and lifecycle management.
/**
* Monaco Editor React component
* @param props - MonacoEditorProps configuration
* @param ref - Forward ref to access editor instance
* @returns React element containing Monaco Editor
*/
declare const MonacoEditor: React.ForwardRefExoticComponent<
MonacoEditorProps & React.RefAttributes<MonacoEditorHandle>
>;Usage Examples:
import React, { useRef, useState } from "react";
import MonacoEditor from "react-monaco-editor";
// Controlled mode with state
function ControlledEditor() {
const [code, setCode] = useState('console.log("Hello World");');
return (
<MonacoEditor
height="400"
language="javascript"
theme="vs-dark"
value={code}
onChange={(newValue) => setCode(newValue)}
options={{
selectOnLineNumbers: true,
minimap: { enabled: false },
fontSize: 14,
}}
/>
);
}
// Uncontrolled mode with ref access
function UncontrolledEditor() {
const editorRef = useRef<{ editor: monaco.editor.IStandaloneCodeEditor }>(null);
const getValue = () => {
if (editorRef.current) {
const value = editorRef.current.editor.getValue();
console.log(value);
}
};
return (
<div>
<button onClick={getValue}>Get Value</button>
<MonacoEditor
ref={editorRef}
height="400"
language="typescript"
defaultValue="// Default content"
editorDidMount={(editor, monaco) => {
editor.focus();
console.log('Editor mounted');
}}
/>
</div>
);
}Full configuration interface for the Monaco Editor component.
interface MonacoEditorProps extends MonacoEditorBaseProps {
/** Value of the auto created model in the editor.
* If you specify `null` or `undefined` for this property, the component behaves in uncontrolled mode.
* Otherwise, it behaves in controlled mode. */
value?: string | null;
/** Refer to Monaco interface {monaco.editor.IStandaloneEditorConstructionOptions}. */
options?: monaco.editor.IStandaloneEditorConstructionOptions;
/** Refer to Monaco interface {monaco.editor.IEditorOverrideServices}. */
overrideServices?: monaco.editor.IEditorOverrideServices;
/** An event emitted before the editor mounted (similar to componentWillMount of React). */
editorWillMount?: EditorWillMount;
/** An event emitted when the editor has been mounted (similar to componentDidMount of React). */
editorDidMount?: EditorDidMount;
/** An event emitted before the editor unmount (similar to componentWillUnmount of React). */
editorWillUnmount?: EditorWillUnmount;
/** An event emitted when the content of the current model has changed. */
onChange?: ChangeHandler;
/** Let the language be inferred from the uri */
uri?: (monaco: typeof monaco) => monaco.Uri;
}Interface for accessing the Monaco Editor instance via React ref.
interface MonacoEditorHandle {
/** Direct access to Monaco editor instance */
editor: monaco.editor.IStandaloneCodeEditor;
}Usage Example:
import React, { useRef } from "react";
import MonacoEditor from "react-monaco-editor";
function EditorWithRef() {
const editorRef = useRef<MonacoEditorHandle>(null);
const insertText = () => {
if (editorRef.current) {
const editor = editorRef.current.editor;
const position = editor.getPosition();
editor.executeEdits("my-source", [{
range: new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column),
text: "Hello World!"
}]);
}
};
return (
<div>
<button onClick={insertText}>Insert Text</button>
<MonacoEditor
ref={editorRef}
height="400"
language="javascript"
defaultValue="// Click button to insert text"
/>
</div>
);
}Callback functions for handling editor lifecycle events.
/**
* Callback invoked before the editor is mounted
* @param monaco - Monaco Editor API instance
* @returns Optional editor construction options to merge with props.options
*/
type EditorWillMount = (
monaco: typeof monaco
) => void | EditorConstructionOptions;
/**
* Callback invoked after the editor has been mounted
* @param editor - The mounted Monaco editor instance
* @param monaco - Monaco Editor API instance
*/
type EditorDidMount = (
editor: monaco.editor.IStandaloneCodeEditor,
monaco: typeof monaco
) => void;
/**
* Callback invoked before the editor is unmounted
* @param editor - The Monaco editor instance being unmounted
* @param monaco - Monaco Editor API instance
*/
type EditorWillUnmount = (
editor: monaco.editor.IStandaloneCodeEditor,
monaco: typeof monaco
) => void | EditorConstructionOptions;
/**
* Callback invoked when editor content changes
* @param value - The new editor content
* @param event - Monaco editor content change event
*/
type ChangeHandler = (
value: string,
event: monaco.editor.IModelContentChangedEvent
) => void;Usage Example:
function EditorWithLifecycle() {
const editorWillMount = (monaco) => {
// Configure JSON schemas before editor mounts
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: [{
uri: "http://myserver/foo-schema.json",
fileMatch: ['*'],
schema: {
type: "object",
properties: {
name: { type: "string" },
version: { type: "string" }
}
}
}]
});
};
const editorDidMount = (editor, monaco) => {
console.log('Editor mounted');
editor.focus();
// Add custom command
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
console.log('Save command triggered');
});
};
const editorWillUnmount = (editor, monaco) => {
console.log('Editor will unmount');
// Cleanup custom resources if needed
};
const onChange = (newValue, event) => {
console.log('Content changed:', newValue);
console.log('Change event:', event);
};
return (
<MonacoEditor
height="400"
language="json"
defaultValue='{"name": "example"}'
editorWillMount={editorWillMount}
editorDidMount={editorDidMount}
editorWillUnmount={editorWillUnmount}
onChange={onChange}
/>
);
}Custom URI creation for Monaco models, useful for language services and validation.
/**
* Function to create a Monaco URI for the editor model
* @param monaco - Monaco Editor API instance
* @returns Monaco URI for the model
*/
uri?: (monaco: typeof monaco) => monaco.Uri;Usage Example:
function EditorWithURI() {
return (
<MonacoEditor
height="400"
language="typescript"
defaultValue="interface User { name: string; }"
uri={(monaco) => monaco.Uri.parse("file:///user-types.ts")}
/>
);
}Frequently used Monaco Editor configuration options:
const commonOptions = {
// Line numbers
lineNumbers: 'on' as const,
lineNumbersMinChars: 3,
// Code folding
folding: true,
foldingStrategy: 'auto' as const,
// Minimap
minimap: { enabled: true },
// Font and rendering
fontSize: 14,
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace',
renderWhitespace: 'selection' as const,
// Selection and cursor
selectOnLineNumbers: true,
roundedSelection: false,
cursorStyle: 'line' as const,
// Layout
automaticLayout: true,
scrollBeyondLastLine: false,
// Editing behavior
wordWrap: 'off' as const,
readOnly: false,
};Install with Tessl CLI
npx tessl i tessl/npm-react-monaco-editor