Monaco Language Client

10.7.0 · active · verified Tue Apr 21

Monaco Language Client (monaco-languageclient), currently at stable version 10.7.0, is a TypeScript-first library designed to bridge the gap between the Monaco Editor and Language Server Protocol (LSP) compatible language servers. It provides the necessary plumbing to integrate rich language features like syntax highlighting, auto-completion, diagnostics, and more into web-based Monaco instances. The library maintains an active release cadence, with major versions like v10 introducing significant architectural shifts. A key differentiator is its deep integration and reliance on `@codingame/monaco-vscode-api`, which allows it to offer a comprehensive toolbox for building VSCode Web-compatible applications, far beyond a simple LSP client. It separates core functionalities into distinct sub-exports, such as `vscodeApiWrapper` for VSCode API handling, `lcwrapper` for managing language clients, and `editorApp` for single editor control, enabling developers to construct sophisticated editor environments. This modular approach, coupled with its focus on modern ESM, makes it a robust solution for complex web-based IDEs.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates the core setup for initializing the VSCode API, configuring a Monaco editor application, and connecting it to a language server via WebSocket using `monaco-languageclient`'s modular components. It illustrates the structured approach required by v10+.

import * as vscode from 'vscode'; // Assumes @codingame/monaco-vscode-api is configured to provide this
import { EditorApp, type EditorAppConfig } from 'monaco-languageclient/editorApp';
import { configureDefaultWorkerFactory } from 'monaco-languageclient/workerFactory';
import { MonacoVscodeApiWrapper, type MonacoVscodeApiConfig } from 'monaco-languageclient/vscodeApiWrapper';
import { LanguageClientWrapper, type LanguageClientConfig } from 'monaco-languageclient/lcwrapper';

// Configure the default worker factory for Monaco, essential for web workers
configureDefaultWorkerFactory();

async function createEditorAndLanguageClient() {
    const languageId = 'mylang';
    const code = `// Welcome to the Monaco Language Client example!\nconst hello: string = "world";\n`;
    // Using vscode.Uri assumes @codingame/monaco-vscode-api is providing the VSCode API.
    const codeUri = vscode.Uri.parse('/workspace/hello.mylang');

    // 1. Monaco VSCode API configuration and initialization
    const vscodeApiConfig: MonacoVscodeApiConfig = {
        $type: 'extended',
        viewsConfig: {
            $type: 'EditorService' // Essential for managing editor views
        }
    };
    const wrapper = new MonacoVscodeApiWrapper();
    // This must be called ONLY ONCE in the application's lifecycle
    await wrapper.initAndStart(vscodeApiConfig);
    console.log('Monaco VSCode API initialized.');

    // 2. Editor Application configuration and setup
    const editorAppConfig: EditorAppConfig = {
        $type: 'codeEditor',
        languageId: languageId,
        code: code,
        uri: codeUri,
        theme: 'vs-dark',
        height: '80vh',
        width: '100%'
    };
    const editorApp = new EditorApp(editorAppConfig);
    editorApp.init();
    editorApp.addEditorLoadedEventListener(() => {
        console.log('Monaco editor loaded!');
    });
    // Mount the editor to a DOM element (e.g., <div id="monaco-editor-root"></div>)
    // Note: In a real app, you'd call editorApp.start(document.getElementById('monaco-editor-root')!); here.

    // 3. Language Client configuration for a WebSocket connection
    const languageClientConfig: LanguageClientConfig = {
        languageId: languageId,
        name: 'My Language Server',
        serverPath: 'ws://localhost:3000/samplelsp', // Replace with your actual language server WebSocket URL
        clientOptions: {
            documentSelector: [{ language: languageId }]
        },
        // Define how to establish and manage the WebSocket connection
        connectionProvider: {
            get: async () => {
                const webSocket = new WebSocket('ws://localhost:3000/samplelsp');
                // You might need more robust error handling and lifecycle management for WebSocket
                return {
                    reader: (event: MessageEvent) => JSON.parse(event.data),
                    writer: (message: any) => webSocket.send(JSON.stringify(message)),
                    dispose: () => webSocket.close(),
                    onError: (cb) => webSocket.addEventListener('error', cb),
                    onClose: (cb) => webSocket.addEventListener('close', cb)
                };
            }
        }
    };
    const languageClient = new LanguageClientWrapper();
    await languageClient.start(languageClientConfig);

    console.log('Monaco Editor and Language Client are configured and starting...');
}

// Execute the setup function
// In a browser environment, call this after the DOM is ready.
createEditorAndLanguageClient().catch(console.error);

view raw JSON →