This repository now hosts multiple npm packages under one roof:
- monaco-languageclient to connect Monaco editor with language servers.
- vscode-ws-jsonrpc which implements communication between a jsonrpc client and server over WebSocket.
- monaco-editor-react makes editor and languageclient available within a react component.
- monaco-languageclient-examples provides the examples which allows to use them externally.
Examples that don't require a backend are now available via GitHub Pages.
- Monaco Language Client, VSCode WebSocket Json RPC, Monaco Editor React and examples
- Changelogs, project history and compatibility
- Getting started
- Usage
- Examples Overview
- Main Examples
- JSON Language client and language server example (Location)
- Python Language client and pyright language server example (Location)
- Groovy Language client and language server example (Location)
- Java Language client and language server example (Location)
- Cpp / Clangd (Location)
- Application Playground (Location)
- Langium grammar DSL (Location)
- Statemachine DSL (created with Langium) (Location)
- bare monaco-languageclient (Location)
- Browser example (Location)
- Purely monaco-editor related examples
- Server processes
- Verification Examples & Usage
- VSCode integration
- Main Examples
- Featured projects
- Troubleshooting
- General
- @codingame/monaco-vscode-editor-api / monaco-editor usage
- Dependency issues: monaco-editor / @codingame/monaco-vscode-api / @codingame/monaco-vscode-editor-api
- Volta
- Vite dev server troubleshooting
- SSR frameworks
- Serve all files required
- Bad Polyfills
- monaco-editor and react
- webpack worker issues
- Licenses
CHANGELOGs for each project are available from the linked location:
- CHANGELOG for
monaco-languageclientis found here - CHANGELOG for
vscode-ws-jsonrpcis found here - CHANGELOG for
@typefox/monaco-editor-reactis found here - CHANGELOG for
monaco-languageclient-examplesis found here
Important Project changes and notes about the project's history are found here.
These are the current versions of packages from this repository and their alignment with @codingame/monaco-vscode-api monaco-editor and vscode:
- monaco-languageclient:
10.0.0(release date: unreleased) - @typefox/monaco-editor-react:
7.0.0(release date: unreleased) - Aligned with:
- @codingame/monaco-vscode-[editor]-api:
^20 - vscode:
1.103.2 - monaco-editor:
0.52.2
- @codingame/monaco-vscode-[editor]-api:
- vscode-ws-jsonrpc:
3.5.0(release date: 2025-08-11)
You find the full compatibility table with all previous versions here.
This article describes the initial motivation for starting monaco-languageclient.
On your local machine you can prepare your dev environment as follows. At first it is advised to build everything. Or, use a fresh dev environment in Gitpod by pressing the code now badge above. Locally, from a terminal do:
git clone https://github.com/TypeFox/monaco-languageclient.git cd monaco-languageclient npm i # Cleans-up, compiles and builds everything npm run buildStart the Vite dev server. It serves all client code at localhost. You can go to the index.html and navigate to all client examples from there. You can edit the client example code directly (TypeScript) and Vite ensures it automatically made available:
npm run dev # OR: this clears the cache and has debug output npm run dev:debugAs this is a npm workspace the main package.json contains script entries applicable to the whole workspace like watch, build and lint, but it also contains shortcuts for launching scripts from the childe packages like npm run build:examples.
If you want to change the libries and see this reflected directly, then you need to run the watch command that compiles all TypeScript files form both libraries and the examples:
npm run watchPlease look at the respective section in the packages:
- Usage for
monaco-languageclientis found here - Usage for
vscode-ws-jsonrpcis found here - Usage for
@typefox/monaco-editor-reactis found here
The examples demonstrate mutliple things:
- How
monaco-languageclientis use bymonaco-edtior-wrapperor@typefox/monaco-editor-reactto have an editor that is connected to a language server either running in the browser in a web worker orvscode-ws-jsonrpc. is used to an external process via web-socket. - How different language servers can be intergrated in a common way, so they can communicate via web-socket to the front-end running in the browser.
JSON Language client and language server example (Location)
The json-server runs an external Node.js Express app where web sockets are used to enable communication between the language server process and the client web application (see JSON Language Server). The json-client contains the editor app which connects to the language server and therefore requires the node server app to be run in parallel.
Python Language client and pyright language server example (Location)
The python-server runs an external Node.js Express app where web sockets are used to enable communication between the language server process and the client web application (see Pyright Language Server). The python-client contains the editor app which connects to the language server and therefore requires the node server app to be run in parallel. It is also possible to use a @typefox/monaco-editor-react app to connect to the server. Both versions now feature a debugger, see here.
Groovy Language client and language server example (Location)
The groovy-server runs an external Java app where web sockets are used to enable communication between the language server process and the client web application (Groovy Language Server). The groovy-client contains the editor app which connects to the language server and therefore requires the node server app to be run in parallel.
Java Language client and language server example (Location)
The java-server runs an external Java app where web sockets are used to enable communication between the language server process and the client web application (Java Language Server). The java-client contains the editor app which connects to the language server and therefore requires the node server app to be run in parallel.
Langium examples (here client and server communicate via vscode-languageserver-protocol/browser instead of a web socket used in the three examples above
Cpp / Clangd (Location)
It contains both the language client and the langauge server (web worker). The clangd language server is compiled to wasm so it can be executed in the browser. Heads up: This is a prototype and still evolving.
Application Playground (Location)
This example uses the view service provider from @codingame/monaco-vscode-editor-api to build an application that utilizes more vscode features. Heads up: This is a prototype and still evolving.
Langium grammar DSL (Location)
It contains both the language client and the langauge server (web worker). Here you can chose beforehand if the wrapper should be started in classic or extended mode.
Statemachine DSL (created with Langium) (Location)
It contains both the language client and the langauge server (web worker). It is also possible to use a @typefox/monaco-editor-react app to connect to the server.
bare monaco-languageclient (Location)
This demonstrates how the JSON Language client and language server example can be realized with just the pure monaco api and no abstraction via the editor app. You find the implementation here.
Browser example (Location)
This demonstrates how an editor app can be combined with a language service written in JavaScript. This example can now be considered legacy as the web worker option eases client side language server implementation and separation, but it still shows a valid way to achieve the desired outcome.
See Typescript Language support.
For the json-client, react-client or the client-webpack examples you need to ensure the json-server example is running:
# start the express server with the language server running in the same process. npm run start:example:server:jsonFor the python-client example you need to ensure the python-server example is running:
# start the express server with the language server running as external node process. npm run start:example:server:pythonIf you want to use the debugger in the python-client example you need to the debugger is running. You require docker-compose to run it. From the project root run docker-compose -f ./packages/examples/resources/debugger/docker-compose.yml up -d. First start up will take longer as the container is downloaded from GitHub's container registry. Use docker-compose -f ./packages/examples/resources/debugger/docker-compose.yml down to stop it.
For the groovy-client example you need to ensure the groovy-server example is running. You require docker-compose which does not require any manual setup (OpenJDK / Gradle). From the project root run docker-compose -f ./packages/examples/resources/groovy/docker-compose.yml up -d. First start up will take longer as the container is downloaded from GitHub's container registry. Use docker-compose -f ./packages/examples/resources/groovy/docker-compose.yml down to stop it.
For the java-client example you need to ensure the java-server example is running. You require docker-compose which does not require any manual setup (OpenJDK / Eclipse JDT LS). From the project root run docker-compose -f ./packages/examples/resources/eclipse.jdt.ls/docker-compose.yml up -d. First start up will take longer as the container is downloaded from GitHub's container registry. Use docker-compose -f ./packages/examples/resources/eclipse.jdt.ls/docker-compose.yml down to stop it.
None of the verification examples is part of the npm workspace. Some bring substantial amount of npm dependencies that pollute the main node_modules dependencies and therefore these examples need to be build and started independently. All verifaction examples re-uses the code form the json client example and therefore require the json server to be started.
-
vite verification example demonstrates how bundling can be achieved with vite. There is no configuration required Please do:
cd verify/vite && npm run verify. It serves the client here: http://localhost:8081. -
webpack verification example demonstrates how bundling can be achieved with webpack. You find the configuration here: webpack.config.js. Please do:
cd verify/webpack && npm run verify. It serves the client here: http://localhost:8082. -
Next.js verification example: demonstrates how to use
@typefox/monaco-editor-reactwith Next.js, Please do:cd verify/next && npm run verify. It serves the client here: http://localhost:8083. -
Currently broken and not usable until repaired: Angular verification example: Before March 2024 this was located in a separate repository. If you want to test it, Please do:
cd verify/angular && npm run verify. It serves the client here: http://localhost:4200.
You can as well run vscode tasks to start and debug the server in different modes and the client.
- JSONA Editor: Showcase (GitHub)
- Clangd in Browser: Showcase (GitHub)
- Langium minilogo using monaco-editor-wrapper: Showcase (GitHub)
Whenever you used monaco-editor/@codingame/monaco-vscode-editor-api vscode/@codingame/monaco-vscode-extension-api, monaco-languageclient or @typefox/monaco-editor-react ensure they are imported before you do any monaco-editor or vscode api related intialization work or start using it.
If you use pnpm or yarn, you have to add vscode / @codingame/monaco-vscode-api as direct dependency, otherwise the installation will fail:
"vscode": "npm:@codingame/monaco-vscode-extension-api@^20"When you use the libraries from this project you are no longer are required to proxy monaco-editor like "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@^20" in you package.json. You can directly use it like this:
import * as monaco from '@codingame/monaco-vscode-editor-api';If your dependency stack already contains a reference monaco-editor you must enforce the correct reference to @codingame/monaco-vscode-editor-api or you will have problems with mismatching code. Useoverrides (npm/pnpm) or resolutions (yarn) to do so:
"overrides": { "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@^20" }Dependency issues: monaco-editor / @codingame/monaco-vscode-api / @codingame/monaco-vscode-editor-api
If you have mutiple, possibly hundreds of compile errors resulting from missing functions deep in monaco-editor or vscode then it is very likely you have a mismatching dependency definition somewhere in your dependency definitions:
- Use
npm list @codingame/monaco-vscode-apito see if there are two different versions are listed in the dependency tree. - If you see a message in the browser console starting with
Another version of monaco-vscode-api has already been loaded. Trying to loadthen definetly a version mismatch was detected by@codingame/monaco-vscode-api. This error is reported since v14.
If one of the two is true, fix you dependencies, remove package-lock.json and node_modules and perform a fresh npm install.
There are Volta instructions in the package.json files. When you have Volta available it will ensure the exactly specified node and npm versions are used.
When you are using the vite dev server there are some issues with imports, please read this recommendation.
If you see the problem Assertion failed (There is already an extension with this id) you likely have mismatching dependencies defined for vscode / @codingame/monaco-vscode-extension-api. You should fix this or add the following entry to your vite config:
resolve: { dedupe: ['vscode'] }Important: Due to its reliance on @codingame/monaco-vscode-api this stack will not directly work with Server-Side Rendering (SSR) frameworks like Next.js. They client code has to be run in a browser environment. Take a look at the Next.js verification example to see how to dynamically load the code.
@codingame/monaco-vscode-api requires json and other files to be served. In your project's web-server configuration you have to ensure you don't prevent this.
If you see an error similar to the one below:
Uncaught Error: Unexpected non—whitespace character after JSON at position 2 SyntaxError: Unexpected non—whitespace character after JSON at position 2 at JSON. parse («anonymous>)It is very likely you have an old version of buffer interfering (see #538 and #546). You can enforce a current version by adding a resolution as shown below to your projects' package.json.
"resolutions": { "buffer": "~6.0.3", }We recommend you now use typefox/monaco-editor-react.
But if you need to use @monaco-editor/react, then add the monaco-editor import at the top of your editor component file source:
import * as monaco from "monaco-editor"; import { loader } from "@monaco-editor/react"; loader.config({ monaco });When webpack is used as bundler there are issues with utilizing the undbundled workers from @codingame/monaco-vscode-api. jhk-mjolner provided a solution in the context of issue #853 here:
-
Npm install
webpack-cli(or webpack will do it for you when you try running this later). -
Create a
bundle-monaco-workers.jsfile with this content:// solve: __dirname is not defined in ES module scope import { fileURLToPath } from 'url'; import { dirname, resolve } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export default { entry: { editor: './node_modules/@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', textmate: './node_modules/@codingame/monaco-vscode-textmate-service-override/worker.js' }, output: { filename: '[name].js', path: resolve(__dirname, './src/assets/monaco-workers'), // if this is true (default), webpack will produce code trying to access global `document` variable for the textmate worker, which will fail at runtime due to being a worker chunkLoading: false }, mode: 'production', performance: { hints: false } };
-
Add this line to your
packages.jsonscripts section:"bundle monaco workers": "webpack --config bundle-monaco-workers.js" -
Run the script
npm run 'bundle monaco workers' -
Configure the
workerLoadersparameter foruseWorkerFactoryto point to the pre-bundled workers:'TextEditorWorker': () => new Worker('/assets/monaco-workers/editor.js', {type: 'module'}), 'TextMateWorker': () => new Worker('/assets/monaco-workers/textmate.js', {type: 'module'}),
-
Enable
editor.experimental.asyncTokenizationin the monaco-wrapper config, if you want to use the textmate worker.