This guide provides solutions to common issues encountered when working with Monaco Language Client. If you can't find a solution here, check our GitHub Issues or consider filing a new one.
Whenever you use 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 initialization 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@^24.2.0"To ensure all Monaco-related packages use a single, compatible version, you must add an override (for npm/pnpm) or resolution (for Yarn) to your package.json.
**npm/pnpm (package.json):**s
{
"overrides": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@^24.2.0"
}
}Yarn (package.json):
{
"resolutions": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@^24.2.0"
}
}If you encounter numerous compile errors deep within monaco-editor or vscode files, you likely have a version mismatch on one or more of your dependencies.
- Check for duplicates: Run
npm list @codingame/monaco-vscode-apito see if multiple versions are installed. - Fix dependencies: Ensure all
@codingame/monaco-vscode-apirelated packages in yourpackage.jsonpoint to the same version. - Reinstall: After fixing versions, delete
node_modulesand your lock file (package-lock.json,pnpm-lock.yaml, etc.) and runnpm install(or equivalent).
Additionally, if you see a message in the browser console starting with Another version of monaco-vscode-api has already been loaded. Trying to load... then definitely a version mismatch was detected by @codingame/monaco-vscode-api. This error is reported since v14.
When you use the libraries from this project you are no longer required to proxy monaco-editor like "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@^24.2.0" in you package.json. You can directly use it like so:
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@^24.2.0"
}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.
buffer: An old version of thebufferpolyfill can cause JSON parsing errors. If you see errors like so:
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>)Then it's 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": { // For Yarn
"buffer": "~6.0.3"
},
"overrides": { // For npm/pnpm
"buffer": "~6.0.3"
}
}If the editor loads but language features (like IntelliSense, diagnostics, or hover information) are missing, check the following:
- Language Server Connection: Ensure your language server is running and accessible. For WebSocket connections, check the browser's developer console for any connection errors.
- Language Client Configuration: Verify that your
languageClientConfigis correct, especially thedocumentSelector. The selector must match the language ID of your editor's model. - Initialization: Make sure all necessary components (
MonacoVscodeApiWrapper,LanguageClientWrapper,EditorApp) are initialized in the correct order. Asynchronous initialization steps should be properly awaited.
- "Another version of monaco-vscode-api has already been loaded": This indicates a version mismatch between Monaco-related packages. See the Dependency Issues section for a solution.
- "Uncaught Error: Unexpected non-whitespace character after JSON at position 2": This is often caused by an outdated
bufferpolyfill. See the Bad Polyfills section.
If the client cannot connect to your WebSocket-based language server:
- Server Status: Verify the language server process is running and listening on the correct port and path.
- URL Mismatch: Double-check the
urlin yourWebSocketUrlconfiguration. - CORS: Ensure your server's Cross-Origin Resource Sharing (CORS) policy allows connections from the origin your web application is served from.
- Firewall/Proxy: Check that no firewalls or network proxies are blocking the WebSocket connection.
If your Web Worker-based language server isn't functioning:
- Bundler Configuration: Ensure your bundler (Vite, Webpack) is correctly configured to handle and output worker files. See the Webpack Worker Issues section for specific guidance.
- File Path: Verify the path to the worker script is correct.
- CORS: If loading the worker from a different origin, ensure CORS headers are correctly set.
When you are using the vite dev server there are some issues with imports, please read this recommendation.
- Assertion failed (There is already an extension with this id): This error occurs when multiple, mismatching versions of
vscode/@codingame/monaco-vscode-extension-apiare bundled. Add adeduperule to yourvite.config.ts:
// vite.config.ts
import { defineConfig } from 'vite';
// ...
export default defineConfig({
resolve: {
dedupe: ['vscode']
}
});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 });Webpack can have trouble with the unbundled workers from @codingame/monaco-vscode-api. jhk-mjolner provided a solution in the context of issue #853 here. To fix this, you need to pre-bundle the workers.
- Install
webpack-cli:npm install --save-dev webpack-cli - Create a bundling script (
bundle-monaco-workers.js) with the following content:
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
},
mode: 'production',
performance: {
hints: false
}
};- Add a script to
package.json:"bundle:workers": "webpack --config bundle-monaco-workers.js" - Run the script:
npm run bundle:workers - Configure the worker factory in your application to point to these pre-bundled workers, by adjusting the
workerLoadersparameter in theuseWorkerFactoryto 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'}),Additionally, if you haven't already, consider enabling async tokenization in your editor config:
{
"editor.experimental.asyncTokenization": true
}Monaco Language Client requires a browser environment and will not run during Server-Side Rendering (SSR). To use it in frameworks like Next.js, you'll need to use dynamic imports to load your editor component dynamically, to ensure it only runs on the client-side.
// ex. pages/editor.tsx
import dynamic from 'next/dynamic';
const MyEditorComponent = dynamic(async () => {
const comp = await import('@typefox/monaco-editor-react');
const { window, workspace, Uri } = (await import('vscode'));
// ... cont setup
}, {
ssr: false,
loading: () => <p>Loading Editor...</p>
});
export default function EditorPage() {
return <MyEditorComponent />;
}For more details, see the Next.js example.
@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.
buffer: An old version of thebufferpolyfill can cause JSON parsing errors. If you see errors like so:
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>)Then it's 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": { // For Yarn
"buffer": "~6.0.3"
},
"overrides": { // For npm/pnpm
"buffer": "~6.0.3"
}
}- Dispose of Instances: Ensure you call the
.dispose()method onEditorApp,LanguageClientWrapper, andMonacoVscodeApiWrapperinstances when they are no longer needed (e.g., when a component unmounts). - Limit Open Files: In a multi-file setup, manage the number of files kept in memory.
- Use Classic Mode: For simpler use cases, Classic Mode has a smaller memory footprint.
-
Async Tokenization: For large files, enable asynchronous tokenization in your editor configuration:
{ "editor.experimental.asyncTokenization": true } -
Web Workers: Offload language server processing to a Web Worker to keep the main UI thread responsive.
To see detailed logs from the language client and server communication, set the logLevel in your MonacoVscodeApiConfig:
import { LogLevel } from '@codingame/monaco-vscode-api';
const vscodeApiConfig = {
// ...
logLevel: LogLevel.Debug
};To inspect the raw Language Server Protocol messages being sent and received, you can enable tracing on the connection. This is highly effective for debugging language server behavior.
// In Classic Mode
const connection = createConnection(webSocket);
connection.trace = 2; // 2 for verbose
// In Extended Mode, this requires custom connection handlingIf your issue is not covered here, please file a bug report on GitHub. A good bug report includes:
- Clear Description: A concise summary of the problem.
- Reproduction Steps: A minimal, self-contained code example that reproduces the issue.
- Versions:
monaco-languageclient,monaco-editor, and Node.js versions. - Logs: Any relevant error messages from the browser console or language server output.