# Vscode Languageclient > NPM Package:`vscode-languageclient` --- # vscode-languageclient Source: https://github.com/microsoft/vscode-languageserver-node/tree/main/client NPM Package: `vscode-languageclient` The client library that allows VSCode extensions to easily integrate language servers adhering to the Language Server Protocol. ## Overview This npm module provides the client-side implementation of the Language Server Protocol for VSCode extensions. It handles the communication between the VSCode editor and the language server running either locally or on a remote machine. ## Installation ```bash npm install vscode-languageclient ``` ## Basic Usage ### Creating a Language Client ```typescript import * as vscode from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node'; let client: LanguageClient; export function activate(context: vscode.ExtensionContext) { // Location of the server module that was shipped with the extension const serverModule = context.asAbsolutePath( join('server', 'out', 'server.js') ); // If the extension is launched in debug mode then the debug server options are used // Otherwise the run options are used const serverOptions: ServerOptions = { run: { module: serverModule, transport: TransportKind.ipc }, debug: { module: serverModule, transport: TransportKind.ipc, options: { execArgv: ['--nolazy', '--inspect=6009'] } } }; // Options to control the language client const clientOptions: LanguageClientOptions = { // Register the server for specific document types documentSelector: [{ scheme: 'file', language: 'mylanguage' }], synchronize: { // Notify the server about file changes to '.clientrc files' fileEvents: vscode.workspace.createFileSystemWatcher('**/.clientrc') } }; // Create the language client and start the client. client = new LanguageClient( 'languageServerExample', 'Language Server Example', serverOptions, clientOptions ); // Start the client. This will also launch the server const disposable = client.start(); // Push the disposable to the context's subscriptions so that the // client can be deactivated on extension deactivation context.subscriptions.push(disposable); } export function deactivate(): Thenable | undefined { if (!client) { return undefined; } return client.stop(); } ``` ## Server Options The `ServerOptions` interface defines how to start the language server: ```typescript interface ServerOptions { run?: Executable | { command: string; args?: string[] }; debug?: Executable | { command: string; args?: string[] }; } interface Executable { command: string; args?: string[]; options?: ExecOptions; } ``` ### Common Transport Types - **ipc** - Node.js inter-process communication (default for local servers) - **stdio** - Standard input/output stream - **socket** - TCP socket connection - **pipe** - Named pipe ### Server Startup Options ```typescript const serverOptions: ServerOptions = { // Run locally via IPC run: { module: serverModule, transport: TransportKind.ipc }, // Run with debugging debug: { module: serverModule, transport: TransportKind.ipc, options: { execArgv: ['--nolazy', '--inspect=6009'], cwd: process.cwd() } } }; ``` ## Client Options The `LanguageClientOptions` interface configures client behavior: ```typescript interface LanguageClientOptions { documentSelector?: DocumentSelector; synchronize?: SynchronizeOptions; diagnosticCollectionName?: string; outputChannelName?: string; revealOutputChannelOn?: RevealOutputChannelOn; stdioEncoding?: string; initializationOptions?: any; initializationFailureHandler?: ( error: ResponseError | Error, client: LanguageClient, clientOptions: LanguageClientOptions ) => boolean; errorHandler?: ErrorHandler; middleware?: ProvideCompletionItemsSignature; uriConverters?: URIConverter; workspaceFolder?: WorkspaceFolder | null; progressOnInitialization?: boolean; } ``` ### Document Selector Specifies which files the language server should handle: ```typescript const clientOptions: LanguageClientOptions = { documentSelector: [ // Handle all TypeScript and JavaScript files { scheme: 'file', language: 'typescript' }, { scheme: 'file', language: 'javascript' }, // Handle untitled/unsaved files { scheme: 'untitled', language: 'typescript' }, // Handle custom URI schemes { scheme: 'custom', language: 'mylanguage' } ] }; ``` ### Synchronize Options Control what file changes are synchronized to the server: ```typescript const clientOptions: LanguageClientOptions = { synchronize: { // Synchronize setting sections to the server configurationSection: ['myLanguage', 'myLanguage.diagnostics'], // Notify the server about file changes to matching patterns fileEvents: [ vscode.workspace.createFileSystemWatcher('**/*.ml'), vscode.workspace.createFileSystemWatcher('**/*.mli'), vscode.workspace.createFileSystemWatcher('**/.ocamlformat') ] } }; ``` ## Client Lifecycle ### Starting the Client ```typescript // Start the client and wait for it to be ready const disposable = client.start(); // Or wait for initialization to complete await client.onReady(); ``` ### Stopping the Client ```typescript // Stop the client (async operation) await client.stop(); ``` ### Deactivation ```typescript export async function deactivate(): Promise { if (client) { await client.stop(); } } ``` ## Middleware Middleware allows you to intercept and modify messages between client and server: ```typescript const clientOptions: LanguageClientOptions = { middleware: { // Intercept completion requests provideCompletionItem: ( document, position, context, token, next ) => { // Pre-processing console.log('Requesting completions at', position); // Call the next handler (could be another middleware or the server) const result = next(document, position, context, token); // Post-processing return result; }, // Intercept hover requests provideHover: (document, position, token, next) => { return next(document, position, token); }, // Intercept diagnostics publishDiagnostics: (uri, diagnostics, next) => { // Filter or modify diagnostics const filtered = diagnostics.filter(d => d.severity === DiagnosticSeverity.Error); return next(uri, filtered); } } }; ``` ### Common Middleware Hooks - `provideCompletionItem` - `provideHover` - `provideSignatureHelp` - `provideDefinition` - `provideReferences` - `provideDocumentHighlights` - `provideCodeActions` - `provideCodeLenses` - `provideDocumentSymbols` - `provideWorkspaceSymbols` - `provideDocumentFormattingEdits` - `provideDocumentRangeFormattingEdits` - `provideOnTypeFormattingEdits` - `provideRenameEdits` - `publishDiagnostics` ## Error Handling Implement custom error handling: ```typescript const errorHandler: ErrorHandler = { error: (error, message, count) => { if (count && count <= 3) { return ErrorAction.Continue; } return ErrorAction.Shutdown; }, closed: () => { return CloseAction.DoNotRestart; } }; const clientOptions: LanguageClientOptions = { errorHandler: errorHandler }; ``` ### Error Action ```typescript enum ErrorAction { Continue = 1, Shutdown = 2 } enum CloseAction { DoNotRestart = 1, Restart = 2 } ``` ## Feature Support The client automatically provides LSP features once the server advertises support: ### Dynamic Feature Registration ```typescript // The server can dynamically register handlers client.onNotification('custom/notification', (params) => { // Handle custom notification }); // The client will unregister handlers when the server requests client.onRequest('custom/request', async (params) => { return { /* response */ }; }); ``` ## Output Channel Access the client's output channel for logging: ```typescript // Get the output channel const outputChannel = client.outputChannel; // Messages are automatically logged here // You can also append your own messages outputChannel.appendLine('Custom message'); outputChannel.show(); ``` ## Configuration Access workspace configuration from your extension: ```typescript // Get configuration const config = vscode.workspace.getConfiguration('myLanguage'); const value = config.get('setting'); // Listen to configuration changes vscode.workspace.onDidChangeConfiguration((event) => { if (event.affectsConfiguration('myLanguage')) { // Reload configuration } }); ``` ## File Operations Watch for file system events: ```typescript const clientOptions: LanguageClientOptions = { synchronize: { fileEvents: vscode.workspace.createFileSystemWatcher('**/*.ml') } }; // Also handle didCreate, didChange, didDelete const watcher = vscode.workspace.createFileSystemWatcher('**/*.json'); watcher.onDidCreate(uri => { // File created }); watcher.onDidChange(uri => { // File changed }); watcher.onDidDelete(uri => { // File deleted }); ``` ## URI Conversion Convert between VSCode URIs and server URIs: ```typescript const clientOptions: LanguageClientOptions = { uriConverters: { code2Protocol: (uri: vscode.Uri): string => uri.toString(true), protocol2Code: (value: string): vscode.Uri => vscode.Uri.parse(value) } }; ``` ## Advanced Features ### Progress Reporting ```typescript // Create a progress indicator vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, title: 'Working...' }, async () => { // Long-running operation await client.sendRequest('custom/longOperation', {}); } ); ``` ### Workspace Folders Work with multiple workspace folders: ```typescript const workspaceFolders = vscode.workspace.workspaceFolders; // Access workspace folder for a document const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); ``` ### Extension Activation Control when the extension activates: ```typescript // package.json { "activationEvents": [ "onLanguage:typescript", "onLanguage:javascript", "onCommand:extension.activate" ] } ``` ## Best Practices 1. **Always dispose of resources** - Push disposables to context.subscriptions 2. **Handle async operations** - Use `await` with client methods 3. **Implement proper error handling** - Don't let errors go unhandled 4. **Monitor server health** - Implement error and close handlers 5. **Use diagnostics collection** - Manage diagnostic collections properly 6. **Synchronize configuration** - Keep server and client config in sync 7. **Test with debugging** - Use the debug configuration to test server startup ## Version History For detailed version history and breaking changes, see the main repository README. The client module is actively maintained and receives regular updates aligned with LSP specification versions.