monaco-languageclient

repository·main·Indexed 23 days ago

https://github.com/typefox/monaco-languageclient

A collection of tools for integrating the Monaco Editor with Language Server Protocol (LSP) capabilities. It includes the monaco-languageclient module for connecting editors to language servers, vscode-ws-jsonrpc for WebSocket-based JSON-RPC communication, and @typefox/monaco-editor-react for React component wrappers. Version 10+ features a modular architecture using MonacoVscodeApiWrapper, LanguageClientWrapper, and EditorApp to manage the VSCode API, language clients, and the editor UI independently.

Tokens
56.7K
Snippets
82
Records
170
Agent score
79%

What's inside monaco-languageclient

  1. Overview of monaco-languageclient

    main

    The monaco-languageclient library enables the integration of the Monaco Editor with language clients and language servers using the Language Server Protocol (LSP). It allows you to build web-based editors with full LSP features such as code completion and diagnostics.

    Key use cases include:

    • Integrating language server features into web applications using Monaco Editor.
    • Building custom language support for specific programming languages in a web environment.
    • Using WebSocket or Web Worker connections to communicate with remote language servers.
  2. Overview of monaco-languageclient packages

    main

    This repository contains several specialized npm packages for integrating Monaco Editor with language servers and React:

    • monaco-languageclient: Connects the Monaco editor with language servers.
    • vscode-ws-jsonrpc: Implements communication between a JSON-RPC client and server over WebSockets.
    • @typefox/monaco-editor-react: Provides React components to make the editor and language client available within a React application.
    • monaco-languageclient-examples: Contains examples that can be used externally.
  3. What is the Monaco Language Client?

    main
    The Monaco Language Client is a TypeScript library that enables the use of the Language Server Protocol (LSP) directly within the monaco-editor. It acts as a communication layer that translates Monaco Editor events (like typing or cursor movement) into LSP messages, sends them to a language server, and applies the responses (such as completions, diagnostics, and go-to-definition) back to the editor. This allows web applications to provide rich, IDE-like language features directly in the browser.
  4. Integrate Langium into a monaco-languageclient application

    main

    To integrate a Langium-based DSL into a web application using monaco-languageclient, you need to focus on two main areas: connecting the language server to the editor and setting up the logic for dispatching and handling notifications and requests.

    These guides assume you have a working Langium language and have completed the basic monaco-languageclient getting started steps.

    For a complete, runnable implementation, refer to the MiniLogo example in the repository, which demonstrates a Langium DSL running in the browser with Monaco using the langium-minilogo package.

  5. Notifications vs. Requests in Langium Language Servers

    main

    When extending communication between a Langium language server and a Monaco client, choose between these two patterns based on the operation's nature:

    FeatureNotificationsRequests
    CommunicationOne-way (fire-and-forget)Round-trip (expects a response)
    Use CaseContinuous, cheap updates (e.g., streaming diagnostics, re-generated output)Expensive or on-demand operations (e.g., generating a file on demand)
    ComplexityLowHigher (requires handling responses/errors)
  6. Initialize Monaco Language Client (Correct Startup Order)

    main

    When setting up the full editor environment, you must initialize the components in a specific order to ensure services and language support are available when the editor starts:

    1. MonacoVscodeApiWrapper.start(): Initializes the VS Code API layer, registers extensions, and sets up editor workers/themes. Must be first.
    2. LanguageClientWrapper.start(): Connects to the language server worker. The API layer must be ready for the client to register itself.
    3. EditorApp.start(): Creates the Monaco editor instance and loads content. This must be last as it relies on the API and language services being ready.

    If you start the EditorApp before these steps, the editor will function but will lack language support and VS Code-related features.

  7. How the Monaco Language Client configuration is structured

    main

    The Monaco Language Client uses a layered configuration approach consisting of three distinct layers:

    1. VSCode API Configuration: Controls editor services and behavior (e.g., themes, keybindings).
    2. Language Client Configuration: Manages the connection to language servers (e.g., WebSocket URLs, document selectors).
    3. Editor App Configuration: Defines code resources and the overall editor setup.

    Regardless of whether you use classic or extended mode, you must configure and start the MonacoVscodeApiWrapper first.

  8. How to run a Langium Language Server in the browser

    main

    Running a Langium-based language server (LS) in the browser involves three main components:

    1. A browser entry point: A file (e.g., main-browser.ts) that starts the language server using browser-compatible communication and file system abstractions.
    2. A bundled worker: The entry point bundled into a standalone Web Worker (typically as an ES module).
    3. A Monaco client: A monaco-languageclient application that loads the worker and establishes a connection.

    This pattern allows you to run the full language intelligence (autocompletion, diagnostics, etc.) entirely on the client side without a Node.js backend.

  9. Compare Notifications vs. Requests in LSP

    main

    When designing communication between a client and a Langium language server, choose between Notifications and Requests based on the following trade-offs:

    FeatureNotificationsRequests
    DirectionOne-wayRound trip
    ResponseNone (fire-and-forget)Awaited response
    Use caseContinuous, semi-frequent updatesOn-demand, as needed
    ExamplePush logs or generated outputGenerate output from a program on click

    Note that both patterns can be used in either direction (client-to-server or server-to-client).

  10. How the Monaco Language Client works

    main

    The library functions as a bridge between the editor and the language server through the following lifecycle:

    1. Receive events from the Monaco Editor (e.g., typing, cursor movement).
    2. Translate events into LSP messages.
    3. Send messages to a language server via WebSockets or Web Workers.
    4. Receive responses from the language server.
    5. Supply the Monaco Editor with language features (completions, diagnostics, etc.).
  11. Compare Extended Mode and Classic Mode integration

    main

    The Monaco Language Client provides two integration modes. Extended Mode is the recommended starting point for most use cases.

    Extended Mode

    Uses @codingame/monaco-vscode-api to provide VSCode-like services.

    • Best for: Applications wanting a full VSCode-like experience, including advanced editor features, extension-like capabilities, and VSCode Web extensions.
    • Key dependency: @codingame/monaco-vscode-api.

    Classic Mode

    Uses a standalone Monaco Editor with language client features added on top.

    • Best for: Lightweight applications that need core LSP features (completions, diagnostics) but want a smaller bundle size and simpler integration without the VSCode API.
    • Trade-off: Lacks the advanced services and features provided by the extended mode.