
Product
Introducing Reachability for PHP
Reachability analysis for PHP is now available in experimental, helping teams identify which vulnerabilities are actually exploitable.
codemirror-languageserver
Advanced tools
This plugin connects a CodeMirror 6 editor with a Language Server over WebSocket, providing IDE-like features in the browser.
https://user-images.githubusercontent.com/348107/120141150-c6bb9180-c1fd-11eb-8ada-9b7b7a1e4ade.mp4
npm i codemirror-languageserver
Peer dependencies: This package requires @codemirror/autocomplete, @codemirror/lint, @codemirror/state, and @codemirror/view as peer dependencies. If you're using CodeMirror 6, you likely already have these installed.
import { EditorState } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { languageServer } from 'codemirror-languageserver';
const ls = languageServer({
serverUri: 'ws://localhost:8080',
rootUri: 'file:///',
documentUri: `file:///${filename}`,
languageId: 'cpp', // As defined at https://microsoft.github.io/language-server-protocol/specification#textDocumentItem.
});
const view = new EditorView({
state: EditorState.create({
extensions: [
// ... other extensions
ls,
],
}),
});
This sets up all built-in features: completion, hover, diagnostics, go-to-definition, document highlight, and rename support.
| Option | Type | Description |
|---|---|---|
serverUri | ws://... or wss://... | WebSocket server URI |
rootUri | string | Root URI of the workspace |
workspaceFolders | WorkspaceFolder[] | LSP workspace folders |
documentUri | string | URI of the document being edited |
languageId | string | Language identifier (spec) |
initializationOptions | object | Server-specific initialization options |
locale | string | Locale for the LSP session (e.g. 'en') |
allowHTMLContent | boolean | Trust raw HTML in hover/completion content (default: false) |
synchronizationMethod | SynchronizationMethod | 'full' or 'incremental' document sync (default: 'full') |
client | LanguageServerClient | Share a client across multiple editor instances |
onCapabilities | (capabilities) => void | Called when server capabilities are available |
onError | (error: Error) => void | Called when the connection encounters an error |
onClose | () => void | Called when the connection is closed |
The plugin does not crash on connection failures. Use onError and onClose to handle disconnections:
languageServer({
serverUri: 'ws://localhost:8080',
rootUri: 'file:///',
documentUri: `file:///${filename}`,
languageId: 'cpp',
onError(error) {
console.error('LSP error:', error);
},
onClose() {
console.log('LSP connection closed');
// Recreate the editor extensions to reconnect
},
})
To share the same language server connection across multiple editor instances:
import { LanguageServerClient, languageServerWithTransport, WebSocketTransport } from 'codemirror-languageserver';
const client = new LanguageServerClient({
transport: new WebSocketTransport('ws://localhost:8080'),
rootUri: 'file:///',
});
// Use the same client for multiple editors
const ls1 = languageServerWithTransport({
client,
documentUri: 'file:///main.cpp',
languageId: 'cpp',
});
const ls2 = languageServerWithTransport({
client,
documentUri: 'file:///utils.cpp',
languageId: 'cpp',
});
Use languageServerWithTransport for non-WebSocket connections:
import { languageServerWithTransport } from 'codemirror-languageserver';
const ls = languageServerWithTransport({
transport: myCustomTransport,
rootUri: 'file:///',
documentUri: `file:///${filename}`,
languageId: 'cpp',
});
The Transport interface:
interface Transport {
send(message: string): void;
onMessage(callback: (message: string) => void): void;
onClose(callback: () => void): void;
onError(callback: (error: Error) => void): void;
close(): void;
}
You can import Transport and WebSocketTransport from the package.
Enabled by default. When the cursor is on a symbol, all occurrences in the document are highlighted. Style with CSS:
.cm-lsp-highlight-text,
.cm-lsp-highlight-read { background-color: rgba(255, 255, 0, 0.2); }
.cm-lsp-highlight-write { background-color: rgba(255, 165, 0, 0.3); }
The three classes correspond to DocumentHighlightKind: general text occurrences, read accesses, and write accesses.
formatDocument and formatSelection are CodeMirror commands — bind them to keys:
import { keymap } from '@codemirror/view';
import { formatDocument, formatSelection } from 'codemirror-languageserver';
const formattingKeymap = keymap.of([
{ key: 'Shift-Alt-f', run: formatDocument },
{ key: 'Ctrl-k Ctrl-f', run: formatSelection },
]);
Configure formatting with the formattingOptions facet. By default, tabSize is read from the editor state.
import { formattingOptions } from 'codemirror-languageserver';
// In extensions:
formattingOptions.of({
tabSize: 2,
insertSpaces: true,
trimTrailingWhitespace: true,
insertFinalNewline: true,
trimFinalNewlines: true,
})
renameSymbol is a CodeMirror command that opens a rename prompt at the top of the editor. If the server supports prepareRename, the current symbol name is used as the placeholder.
import { keymap } from '@codemirror/view';
import { renameSymbol } from 'codemirror-languageserver';
const renameKeymap = keymap.of([
{ key: 'F2', run: renameSymbol },
]);
Style the panel with CSS:
.cm-lsp-rename-panel {
padding: 4px 8px;
border-bottom: 1px solid #ddd;
}
.cm-lsp-rename-input {
font-family: inherit;
font-size: inherit;
}
Use the onCapabilities callback to react when the server finishes initializing — e.g. to show or hide toolbar buttons:
languageServer({
serverUri: 'ws://localhost:8080',
rootUri: 'file:///',
documentUri: `file:///${filename}`,
languageId: 'cpp',
onCapabilities(capabilities) {
// capabilities.documentFormattingProvider
// capabilities.renameProvider
// capabilities.completionProvider
// etc.
toolbar.update({ capabilities });
},
})
The package includes TypeScript definitions for popular language servers:
PyrightInitializationOptions — Python (Pyright)RustAnalyzerInitializationOptions — Rust (rust-analyzer)TypeScriptInitializationOptions — TypeScript/JavaScriptESLintInitializationOptions — ESLintClangdInitializationOptions — C/C++ (Clangd)GoplsInitializationOptions — Go (Gopls)import { languageServer } from 'codemirror-languageserver';
import type { ClangdInitializationOptions } from 'codemirror-languageserver';
const ls = languageServer<ClangdInitializationOptions>({
serverUri: 'ws://localhost:8080',
rootUri: 'file:///',
documentUri: 'file:///main.cpp',
languageId: 'cpp',
initializationOptions: {
// Type-checked options specific to Clangd
},
});
Contributions are welcome.
The library is available under the BSD (3-Clause) License.
FAQs
Language Server Plugin for CodeMirror 6
We found that codemirror-languageserver demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Reachability analysis for PHP is now available in experimental, helping teams identify which vulnerabilities are actually exploitable.

Product
Export Socket alert data to your own cloud storage in JSON, CSV, or Parquet, with flexible snapshot or incremental delivery.

Research
/Security News
Bitwarden CLI 2026.4.0 was compromised in the Checkmarx supply chain campaign after attackers abused a GitHub Action in Bitwarden’s CI/CD pipeline.