MCPcopy
hub / github.com/suren-atoyan/monaco-react

github.com/suren-atoyan/monaco-react @v4.7.0 sqlite

repository ↗ · DeepWiki ↗ · release v4.7.0 ↗
61 symbols 224 edges 84 files 5 documented · 8%
README

@monaco-editor/react · monthly downloads gitHub license npm version PRs welcome

Monaco Editor for React · use the monaco-editor in any React application without needing to use webpack (or rollup/parcel/etc) configuration files / plugins


  • :loudspeaker: for React v19 users: check out the v4.7.0-rc.0 version (use npm install @monaco-editor/react@next or yarn add @monaco-editor/react@next) and let us know if you face any issues
  • :keyboard: rewritten with TypeScript :fire:
  • :zap: multi-model editor is already supported; enjoy it :tada:
  • :tada: version v4 is here - to see what's new in the new version and how to migrate from v3, please read this doc (also, if you need the old version README, it's here)
  • :video_game: the new section Development / Playground has been created - now you can run the playground and play with the internals of the library
  • :dizzy: it's already integrated with @monaco-editor/loader

Synopsis

Monaco editor wrapper for easy/one-line integration with any React application without needing to use webpack (or any other module bundler) configuration files / plugins. It can be used with apps generated by create-react-app, create-snowpack-app, vite, Next.js or any other app generators - you don't need to eject or rewire them.

Motivation

The monaco-editor is a well-known web technology based code editor that powers VS Code. This library handles the setup process of the monaco-editor and provides a clean API to interact with monaco from any React environment

Demo

Check it out!

Documentation

Installation

npm install @monaco-editor/react # or @monaco-editor/react@next for React v19

or

yarn add @monaco-editor/react

or you can use CDN. Here is an example

NOTE: For TypeScript type definitions, this package uses the monaco-editor package as a peer dependency. So, if you need types and don't already have the monaco-editor package installed, you will need to do so

Ask AI

Monaco-React AI will help you understand this repository better. You can ask for code examples, installation guide, debugging help and much more.

Introduction

Besides types, the library exports Editorand DiffEditor components, as well as the loader utility and the useMonaco hook:

import Editor, { DiffEditor, useMonaco, loader } from '@monaco-editor/react';

Usage

Simple usage

Here is an example of a simple integration of monaco editor with a React project.

You just need to import and render the Editor component:

import React from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  return <Editor height="90vh" defaultLanguage="javascript" defaultValue="// some comment" />;
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

Extended example

import React from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  function handleEditorChange(value, event) {
    // here is the current value
  }

  function handleEditorDidMount(editor, monaco) {
    console.log('onMount: the editor instance:', editor);
    console.log('onMount: the monaco instance:', monaco);
  }

  function handleEditorWillMount(monaco) {
    console.log('beforeMount: the monaco instance:', monaco);
  }

  function handleEditorValidation(markers) {
    // model markers
    // markers.forEach(marker => console.log('onValidate:', marker.message));
  }

  return (
    <Editor
      height="90vh"
      defaultLanguage="javascript"
      defaultValue="// some comment"
      onChange={handleEditorChange}
      onMount={handleEditorDidMount}
      beforeMount={handleEditorWillMount}
      onValidate={handleEditorValidation}
    />
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

Get value

There are two options to get the current value:

  1. get the current model value from the editor instance
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  const editorRef = useRef(null);

  function handleEditorDidMount(editor, monaco) {
    editorRef.current = editor;
  }

  function showValue() {
    alert(editorRef.current.getValue());
  }

  return (
    <>
      <button onClick={showValue}>Show value</button>
      <Editor
        height="90vh"
        defaultLanguage="javascript"
        defaultValue="// some comment"
        onMount={handleEditorDidMount}
      />
    </>
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

  1. get the current model value via onChange prop
import React from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  function handleEditorChange(value, event) {
    console.log('here is the current model value:', value);
  }

  return (
    <Editor
      height="90vh"
      defaultLanguage="javascript"
      defaultValue="// some comment"
      onChange={handleEditorChange}
    />
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

(get the DiffEditor values via editor instance)

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';

import { DiffEditor } from '@monaco-editor/react';

function App() {
  const diffEditorRef = useRef(null);

  function handleEditorDidMount(editor, monaco) {
    diffEditorRef.current = editor;
  }

  function showOriginalValue() {
    alert(diffEditorRef.current.getOriginalEditor().getValue());
  }

  function showModifiedValue() {
    alert(diffEditorRef.current.getModifiedEditor().getValue());
  }

  return (
    <>
      <button onClick={showOriginalValue}>show original value</button>
      <button onClick={showModifiedValue}>show modified value</button>
      <DiffEditor
        height="90vh"
        language="javascript"
        original="// the original code"
        modified="// the modified code"
        onMount={handleEditorDidMount}
      />
    </>
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

editor instance

The editor instance is exposed from the onMount prop as a first parameter, the second is the monaco instance

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  const editorRef = useRef(null);

  function handleEditorDidMount(editor, monaco) {
    // here is the editor instance
    // you can store it in `useRef` for further usage
    editorRef.current = editor;
  }

  return (
    <Editor
      height="90vh"
      defaultLanguage="javascript"
      defaultValue="// some comment"
      onMount={handleEditorDidMount}
    />
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

monaco instance

There are three options to get the monaco instance:

  1. via onMount/beforeMount
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';

import Editor from '@monaco-editor/react';

function App() {
  const monacoRef = useRef(null);

  function handleEditorWillMount(monaco) {
    // here is the monaco instance
    // do something before editor is mounted
    monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true);
  }

  function handleEditorDidMount(editor, monaco) {
    // here is another way to get monaco instance
    // you can also store it in `useRef` for further usage
    monacoRef.current = monaco;
  }

  return (
    <Editor
      height="90vh"
      defaultLanguage="javascript"
      defaultValue="// some comment"
      beforeMount={handleEditorWillMount}
      onMount={handleEditorDidMount}
    />
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

  1. via loader utility
import { loader } from '@monaco-editor/react';

loader.init().then((monaco) => console.log('here is the monaco instance:', monaco));

codesandbox

  1. via useMonaco hook
import React from 'react';
import ReactDOM from 'react-dom';

import Editor, { useMonaco } from '@monaco-editor/react';

function App() {
  const monaco = useMonaco();

  useEffect(() => {
    if (monaco) {
      console.log('here is the monaco instance:', monaco);
    }
  }, [monaco]);

  return <Editor height="90vh" defaultValue="// some comment" defaultLanguage="javascript" />;
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

useMonaco

useMonaco is a React hook that returns the instance of the monaco. But there is an important note that should be considered: the initialization process is being handled by the loader utility (the reference of @monaco-editor/loader): that process is being done asynchronously and only once. So, if the first initiator of the initialization is useMonaco hook, the first returned value will be null, due to its asynchronous installation. Just check the returned value of useMonaco

import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';

import Editor, { useMonaco } from '@monaco-editor/react';

function App() {
  const monaco = useMonaco();

  useEffect(() => {
    // do conditional chaining
    monaco?.languages.typescript.javascriptDefaults.setEagerModelSync(true);
    // or make sure that it exists by other ways
    if (monaco) {
      console.log('here is the monaco instance:', monaco);
    }
  }, [monaco]);

  return <Editor height="90vh" defaultValue="// some comment" defaultLanguage="javascript" />;
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

codesandbox

loader-config

The library exports (named) the utility called loader. Basically, it's the reference of @monaco-editor/loader. By default, monaco files are being downloaded from CDN. There is an ability to change this behavior, and other things concerning the AMD loader of monaco. We have a default config file that you can modify by the way shown below:

import { loader } from '@monaco-editor/react';

// you can change the source of the monaco files
loader.config({ paths: { vs: '...' } });

// you can configure the locales
loader.config({ 'vs/nls': { availableLanguages: { '*': 'de' } } });

// or
loader.config({
  paths: {
    vs: '...',
  },
  'vs/nls': {
    availableLanguages: {
      '*': 'de',
    },
  },
});
use monaco-editor as an npm package

Starting from version v4.4.0 it's possible to use monaco-editor as an npm package; import it from node_modules and include monaco sou

Core symbols most depended-on inside this repo

rTabs
called by 57
demo/src/utils/rTabs.js
useUpdate
called by 13
src/hooks/useUpdate/index.ts
getOrCreateModel
called by 6
src/utils/index.ts
f
called by 5
demo/public/polyfill.js
useMount
called by 3
src/hooks/useMount/index.ts
setIsEditorReady
called by 3
demo/src/store/actions/index.js
setSelectedLanguageId
called by 3
demo/src/store/actions/index.js
createModelUri
called by 2
src/utils/index.ts

Shape

Function 61

Languages

TypeScript100%

Modules by API surface

demo/src/store/actions/index.js8 symbols
demo/src/sections/Editor/Settings/Settings.js6 symbols
demo/public/polyfill.js6 symbols
src/utils/index.ts5 symbols
demo/src/serviceWorker.js4 symbols
src/Editor/Editor.tsx2 symbols
src/DiffEditor/DiffEditor.tsx2 symbols
demo/src/utils/asyncComponentLoader.js2 symbols
demo/src/sections/Header/Header.js2 symbols
src/hooks/useUpdate/index.ts1 symbols
src/hooks/usePrevious/index.ts1 symbols
src/hooks/useMount/index.ts1 symbols

Dependencies from manifests, versioned

@material-ui/core4.5.0 · 1×
@material-ui/icons4.4.3 · 1×
@material-ui/lab4.0.0-alpha.28 · 1×
@material-ui/styles4.5.0 · 1×
@monaco-editor/loader1.5.0 · 1×
@monaco-editor/react4.1.3 · 1×
@testing-library/react14.0.0 · 1×
@typescript-eslint/eslint-plugin5.54.0 · 1×
@typescript-eslint/parser5.54.0 · 1×
@vitejs/plugin-react-swc3.2.0 · 1×
classnames2.2.6 · 1×

For agents

$ claude mcp add monaco-react \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact