| |

TypeScript 100 ๐Ÿ”ท Language Server Protocol and Editor Integration

The Language Server Protocol is the interface that lets editors and IDEs provide rich language features โ€” completions, diagnostics, hover information, go-to-definition, refactoring โ€” without implementing a language’s compiler inside the editor itself. A language server runs as a separate process, communicates with the editor through a standardized protocol, and exposes the language’s semantic model to any editor that speaks the protocol. TypeScript’s implementation of this model is called tsserver, and it predates the LSP itself. In fact, the LSP was born from the TypeScript server’s protocol .

Key point: The LSP is a language-neutral protocol. It defines the messages that an editor and a language server exchange, regardless of which language the server implements. TypeScript’s tsserver uses its own JSON protocol, which is not the LSP. A separate community project, typescript-language-server, wraps tsserver and exposes it through the LSP so that editors outside VS Code can use standardized plumbing . TypeScript 7.0 is changing this by adding native LSP support .


Why the Language Server Protocol exists

Before the LSP, every editor that wanted to support a language had to implement that language’s tooling inside the editor itself. The Eclipse CDT plugin for C/C++ was written in Java because Eclipse is written in Java. A Visual Studio Code plugin for C/C++ would have to be written in TypeScript, and a Visual Studio plugin in C#. The same language’s domain model had to be reimplemented for every editor. With n editors and m languages, the number of plugins required was n ร— m .

The LSP changes the equation to n + m. Each language implements one language server. Each editor implements one LSP client. Any editor can talk to any server. The protocol standardizes the messages: textDocument/completion for completions, textDocument/hover for hover information, textDocument/definition for go-to-definition, and so on. The editor does not need to understand the language’s internal model. It only needs to send the right request and render the response .

The LSP started with OmniSharp for C#, then the TypeScript server, and was standardized by the VS Code team. The TypeScript server’s protocol was the foundation. The LSP extended it with more language features inspired by the VS Code language API. JSON-RPC was chosen for the remote invocation because of its simplicity and existing libraries .


a. tsserver: The TypeScript Standalone Server

tsserver is a Node.js executable that encapsulates the TypeScript compiler and language services. It exposes them through a JSON protocol defined in tsserverlibrary.d.ts. The server listens on stdin and writes responses to stdout. Each message is a JSON object with a header that includes the content length, followed by the JSON body .

A request to open a file looks like this:

{"seq":1,"type":"request","command":"open","arguments":{"file":"c:/project/index.ts"}}

A response to a quick-info request looks like this:

Content-Length: 116

{"seq":0,"type":"response","command":"quickinfo","request_seq":2,"success":false,"message":"No content available."}

The server supports a set of commands: open, close, completionInfo, quickinfo, definition, references, rename, geterr, geterrForProject, format, organizeImports, getCodeFixes, and many more. Each command has a corresponding request and response interface in the protocol definition .

VS Code’s TypeScript support is built on tsserver. The built-in typescript-language-features extension spawns the server as a child process and communicates with it using the JSON protocol. VS Code does not use the LSP for TypeScript โ€” it uses tsserver directly. This is why VS Code’s TypeScript support is richer and more responsive than editors that rely on the LSP wrapper .


b. typescript-language-server: The LSP Wrapper

Editors outside VS Code โ€” Neovim, Emacs, Sublime Text, Helix โ€” do not want to implement the tsserver protocol. They want to speak the LSP because their LSP client infrastructure already exists. The typescript-language-server project bridges the gap. It is a community-maintained server that implements the LSP and translates LSP requests into tsserver requests .

The server is installed with npm:

npm install -g typescript-language-server typescript@6

It is started with the --stdio flag and communicates with the editor over standard input and output. The editor sends LSP requests. The server translates them to tsserver commands, forwards them to a spawned tsserver process, receives the response, and translates it back to an LSP response .

The server exposes TypeScript-backed code actions, workspace commands, code lenses, inlay hints, formatting requests, and passthrough commands that allow the editor to send raw tsserver commands when the LSP does not have an equivalent . The project is not maintained by Microsoft and is not used in VS Code. It exists purely for editors that want TypeScript support through LSP plumbing .

The translation is not perfect. Some TypeScript-specific features โ€” like the “Move to File” refactor, which requires user input that the LSP does not have a standard for โ€” cannot be exposed through the LSP without custom extensions. The server implements these as custom workspace commands with the _typescript. prefix .


c. TypeScript 7.0 and Native LSP Support

TypeScript 7.0, released in July 2026, is a native Go port of the compiler that delivers 8xโ€“12x speedups on full builds. A full build of the VS Code codebase, for example, fell from 125.7 seconds to 10.6 seconds. Opening a file with an error dropped from 17.5 seconds to under 1.3 seconds .

The performance gain comes from native code, shared memory multithreading, and a more efficient traversal of the syntax graph. The language service has been rewritten to use the LSP natively. VS Code has a dedicated TypeScript 7 extension, and support is being migrated from the older tsserver design to the LSP .

This change matters for editors outside VS Code. When TypeScript 7.0 ships with native LSP support, the community typescript-language-server wrapper may become unnecessary. The native server will speak LSP directly, and any LSP-capable editor can use it without a translation layer. The typescript-language-server maintainers acknowledge this: “Currently Microsoft is working on TypeScript 7 written natively in the go language that will include the LSP implementation and will hopefully supersede this project” .

The migration is not complete. tsserver still exists in TypeScript 7.0, and VS Code still uses it for some features. But the direction is clear: the LSP is the future of TypeScript editor integration, and the standalone server is being replaced by a native LSP server .


Complete Example Session

This session demonstrates how an editor communicates with tsserver, how the LSP wrapper translates requests, and how the TypeScript 7.0 change affects the setup.

// ============================================
// PART 1: A REQUEST TO TSSERVER
// ============================================

// The editor sends a request to open a file
// {"seq":1,"type":"request","command":"open","arguments":{"file":"/project/index.ts"}}

// tsserver responds with the file's syntactic diagnostics
// {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"/project/index.ts","diagnostics":[]}}

// ============================================
// PART 2: A COMPLETION REQUEST
// ============================================

// The editor sends a completion request
// {"seq":2,"type":"request","command":"completionInfo",
//  "arguments":{"file":"/project/index.ts","line":5,"offset":10}}

// tsserver responds with the completion entries
// {"seq":0,"type":"response","command":"completionInfo","request_seq":2,"success":true,
//  "body":{"isGlobalCompletion":false,"isMemberCompletion":false,
//          "entries":[{"name":"length","kind":"property","sortText":"0"}]}}

// ============================================
// PART 3: THE LSP EQUIVALENT
// ============================================

// The editor sends an LSP completion request
// {"jsonrpc":"2.0","id":1,"method":"textDocument/completion",
//  "params":{"textDocument":{"uri":"file:///project/index.ts"},
//            "position":{"line":5,"character":10}}}

// typescript-language-server translates it to a tsserver request,
// gets the response, and translates it back to LSP
// {"jsonrpc":"2.0","id":1,"result":{
//   "isIncomplete":false,
//   "items":[{"label":"length","kind":10,"sortText":"0"}]}}

// ============================================
// PART 4: THE VS CODE CONFIGURATION
// ============================================

// .vscode/settings.json
{
  "js/ts.tsdk.path": "node_modules/typescript/lib",
  "js/ts.tsdk.promptToUseWorkspaceVersion": true
}

// The tsdk.path setting tells VS Code to use the workspace's
// TypeScript version instead of the bundled version.
// The prompt setting controls whether VS Code asks the user
// to confirm the switch .

// ============================================
// PART 5: THE NEVOIM CONFIGURATION
// ============================================

// Neovim uses the LSP client and typescript-language-server
// require('lspconfig').tsserver.setup({
//   cmd = { "typescript-language-server", "--stdio" },
//   root_dir = require('lspconfig.util').root_pattern("tsconfig.json"),
// })

// The LSP client sends LSP requests.
// typescript-language-server translates them to tsserver.

// ============================================
// PART 6: THE TSSERVER LOG
// ============================================

// Set the TSS_LOG environment variable to capture the protocol
// TSS_LOG="-level verbose -file /tmp/tsserver.log"

// The log contains every request and response.
// It is the primary debugging tool for editor integration issues.

// ============================================
// PART 7: THE LANGUAGE SERVICE PLUGIN
// ============================================

// A TypeScript language service plugin can extend tsserver's behavior.
// It is registered in tsconfig.json:
// { "compilerOptions": { "plugins": [{ "name": "my-plugin" }] } }

// The plugin receives the language service and can proxy its methods.
// It can modify completions, refactorings, and diagnostics .

// ============================================
// PART 8: THE TYPESCRIPT 7.0 CHANGE
// ============================================

// TypeScript 7.0 ships with native LSP support.
// VS Code uses a dedicated TypeScript 7 extension.
// The community typescript-language-server may become unnecessary.

// For editors that already speak LSP, the transition is transparent.
// The server command changes, but the protocol remains the same.

// ============================================
// PART 9: THE DEBUGGING WORKFLOW
// ============================================

// To debug tsserver:
// 1. Set TSS_DEBUG to an open port
// 2. Launch VS Code with the development TypeScript build
// 3. Attach the debugger to the port 

// The server-side code lives in src/services and src/server
// of the TypeScript repository. The client-side code lives in
// extensions/typescript of the VS Code repository .

// ============================================
// PART 10: THE SUMMARY
// ============================================

// tsserver: TypeScript's standalone server, JSON protocol.
// LSP: language-neutral protocol, n + m plugins instead of n ร— m.
// typescript-language-server: LSP wrapper around tsserver.
// TypeScript 7.0: native LSP support, Go-based compiler.

The ten parts cover a tsserver request, a completion request, the LSP equivalent, VS Code configuration, Neovim configuration, tsserver logging, language service plugins, the TypeScript 7.0 change, debugging workflow, and the summary.


Quick Reference

The Protocol Comparison

AspecttsserverLSP
ScopeTypeScript/JavaScriptAny language
ProtocolCustom JSONJSON-RPC 2.0
Transportstdin/stdoutstdio, sockets
Editor supportVS Code, othersAny LSP client
Native supportTypeScriptStandardized

The Key Projects

ProjectPurpose
tsserverTypeScript standalone server
typescript-language-serverLSP wrapper around tsserver
typescript-language-featuresVS Code extension
TypeScript 7.0Native LSP server

The LSP Request Methods

MethodPurpose
textDocument/completionCode completions
textDocument/hoverHover information
textDocument/definitionGo to definition
textDocument/referencesFind references
textDocument/renameRename symbol
textDocument/codeActionRefactoring and fixes
textDocument/formattingFormat document

The tsserver Commands

CommandPurpose
openOpen a file
closeClose a file
completionInfoGet completions
quickinfoGet hover info
definitionGet definition location
referencesGet reference locations
renameGet rename edits
geterrGet semantic diagnostics
formatFormat a file
organizeImportsOrganize imports

The Configuration Settings

SettingPurpose
js/ts.tsdk.pathUse workspace TypeScript
js/ts.tsdk.promptToUseWorkspaceVersionPrompt for workspace version
TSS_LOGEnable tsserver logging
TSS_DEBUGEnable tsserver debugging

Best Practices

โœ… Do This:

// Use the workspace TypeScript version in VS Code
{ "js/ts.tsdk.path": "node_modules/typescript/lib" }          // โœ…
# Use typescript-language-server for LSP editors
npm install -g typescript-language-server typescript@6        // โœ…
# Enable tsserver logging for debugging
TSS_LOG="-level verbose -file /tmp/tsserver.log"              // โœ…
// Write a language service plugin to extend tsserver
// { "compilerOptions": { "plugins": [{ "name": "my-plugin" }] } } // โœ…

โŒ Don’t Do This:

# Don't try to connect to tsserver using LSP
# tsserver uses its own JSON protocol, not LSP.               // โŒ
// Don't put tsdk.path in user settings if the path is relative
// It must be relative to the workspace folder.               // โŒ
// Don't assume all TypeScript features are available in LSP
// Some features require tsserver-specific extensions.        // โŒ

Common Pitfalls

PitfallWhy It HappensFix
LSP client cannot connectUsing LSP to talk to tsserverUse typescript-language-server wrapper
Editor shows older TypeScriptUsing bundled versionSet js/ts.tsdk.path
Missing completionsLanguage server not startedCheck the editor’s LSP configuration
Slow diagnosticsLarge project, no incrementalUse tsserver project system
TypeScript 7.0 LSP not workingUsing old typescript-language-serverUse native TypeScript 7 LSP

Real-World Examples

1. tsserver Request

{"seq":1,"type":"request","command":"open","arguments":{"file":"/project/index.ts"}}

2. tsserver Response

Content-Length: 116

{"seq":0,"type":"response","command":"quickinfo","request_seq":2,"success":false}

3. LSP Completion Request

{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///project/index.ts"},"position":{"line":5,"character":10}}}

4. VS Code Setting

{ "js/ts.tsdk.path": "node_modules/typescript/lib" }

5. Neovim LSP Setup

require('lspconfig').tsserver.setup({ cmd = { "typescript-language-server", "--stdio" } })

6. tsserver Logging

TSS_LOG="-level verbose -file /tmp/tsserver.log" tsserver

7. Language Service Plugin

{ "compilerOptions": { "plugins": [{ "name": "my-plugin" }] } }

8. Debug tsserver

TSS_DEBUG=5859 code --user-data-dir=/tmp/vscode-dev

9. TypeScript 7.0 LSP

# VS Code has a dedicated TypeScript 7 extension
# The native server speaks LSP directly

10. typescript-language-server

typescript-language-server --stdio

Visual

The LSP Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  LSP ARCHITECTURE                            โ”‚
โ”‚                                              โ”‚
โ”‚  Editor (LSP client)                         โ”‚
โ”‚    โ”‚                                         โ”‚
โ”‚    โ”‚  JSON-RPC over stdio                    โ”‚
โ”‚    โ–ผ                                         โ”‚
โ”‚  Language Server (LSP server)                โ”‚
โ”‚    โ”‚                                         โ”‚
โ”‚    โ–ผ                                         โ”‚
โ”‚  Language domain model                       โ”‚
โ”‚    (compiler, parser, checker)               โ”‚
โ”‚                                              โ”‚
โ”‚  n editors + m languages = n + m plugins     โ”‚
โ”‚  Without LSP: n ร— m plugins                  โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The TypeScript Editor Integration

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  TYPESCRIPT EDITOR INTEGRATION               โ”‚
โ”‚                                              โ”‚
โ”‚  VS Code:                                    โ”‚
โ”‚    typescript-language-features              โ”‚
โ”‚      โ””โ”€ spawns tsserver                      โ”‚
โ”‚      โ””โ”€ JSON protocol (stdin/stdout)         โ”‚
โ”‚                                              โ”‚
โ”‚  Neovim / Emacs / Sublime:                   โ”‚
โ”‚    LSP client                                โ”‚
โ”‚      โ””โ”€ typescript-language-server           โ”‚
โ”‚           โ””โ”€ wraps tsserver                  โ”‚
โ”‚           โ””โ”€ translates LSP โ†” tsserver       โ”‚
โ”‚                                              โ”‚
โ”‚  TypeScript 7.0:                             โ”‚
โ”‚    Native LSP server (Go)                    โ”‚
โ”‚      โ””โ”€ No wrapper needed                    โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The tsserver Protocol

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  TSSERVER PROTOCOL                           โ”‚
โ”‚                                              โ”‚
โ”‚  Request:                                    โ”‚
โ”‚  {"seq":1,"type":"request",                  โ”‚
โ”‚   "command":"completionInfo",                โ”‚
โ”‚   "arguments":{"file":"...", "line":5,       โ”‚
โ”‚                "offset":10}}                 โ”‚
โ”‚                                              โ”‚
โ”‚  Response:                                   โ”‚
โ”‚  Content-Length: <n>                         โ”‚
โ”‚  {"seq":0,"type":"response",                 โ”‚
โ”‚   "command":"completionInfo",                โ”‚
โ”‚   "request_seq":1,"success":true,            โ”‚
โ”‚   "body":{"entries":[...]}}                  โ”‚
โ”‚                                              โ”‚
โ”‚  Event:                                      โ”‚
โ”‚  {"seq":0,"type":"event",                    โ”‚
โ”‚   "event":"semanticDiag",                    โ”‚
โ”‚   "body":{"file":"...", "diagnostics":[...]}}โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The TypeScript 7.0 Change

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  TYPESCRIPT 6 vs 7 EDITOR SUPPORT            โ”‚
โ”‚                                              โ”‚
โ”‚  TypeScript 6:                               โ”‚
โ”‚    tsserver (Node.js)                        โ”‚
โ”‚    Custom JSON protocol                      โ”‚
โ”‚    VS Code uses tsserver directly            โ”‚
โ”‚    Other editors use wrapper                 โ”‚
โ”‚                                              โ”‚
โ”‚  TypeScript 7:                               โ”‚
โ”‚    Native server (Go)                        โ”‚
โ”‚    Native LSP support                        โ”‚
โ”‚    VS Code uses dedicated extension          โ”‚
โ”‚    Other editors use LSP directly            โ”‚
โ”‚                                              โ”‚
โ”‚  Speedup: 8xโ€“12x on full builds              โ”‚
โ”‚  Editor: <1.3s to open file with error       โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
LSPLanguage Server Protocol, language-neutral
LSP purposen + m plugins instead of n ร— m
tsserverTypeScript standalone server
tsserver protocolCustom JSON over stdin/stdout
LSP wrappertypescript-language-server
VS Code integrationUses tsserver directly
Neovim/Emacs integrationUses LSP wrapper
TypeScript 7.0Native LSP support, Go compiler
DebuggingTSS_LOG, TSS_DEBUG
Workspace TypeScriptjs/ts.tsdk.path

Key takeaways:

  • The LSP is the standardized protocol between editors and language servers. It defines the messages for completions, diagnostics, hover, definition, rename, and refactoring. The n + m architecture replaces the n ร— m model of per-editor plugins .
  • tsserver is TypeScript’s standalone server. It predates the LSP and uses its own JSON protocol over stdin/stdout. VS Code communicates with it directly. It supports a set of commands defined in tsserverlibrary.d.ts .
  • typescript-language-server wraps tsserver for LSP editors. It translates LSP requests into tsserver commands and back. This is how Neovim, Emacs, Sublime Text, and Helix get TypeScript support .
  • VS Code does not use the LSP for TypeScript. It uses tsserver directly through the typescript-language-features extension. This is why VS Code’s TypeScript support is richer and more responsive than editors that use the wrapper .
  • TypeScript 7.0 adds native LSP support. The Go-based compiler includes an LSP server. VS Code has a dedicated extension. The community wrapper may become unnecessary. The performance gains are significant: 8xโ€“12x on full builds, and sub-1.3-second file opens in the VS Code codebase .
  • The workspace TypeScript version can be selected in VS Code. The js/ts.tsdk.path setting points to node_modules/typescript/lib. The js/ts.tsdk.promptToUseWorkspaceVersion setting controls the confirmation prompt. This ensures the editor uses the same TypeScript version as the project .
  • Language service plugins extend tsserver. They are registered in tsconfig.json under compilerOptions.plugins. They receive the language service and can proxy its methods to modify completions, refactorings, and diagnostics .

Remember: The Language Server Protocol is the interface that decouples editors from language implementations. TypeScript’s tsserver was the foundation of the LSP, and it remains the server that VS Code uses directly. Other editors use the typescript-language-server wrapper to translate LSP requests into tsserver commands. TypeScript 7.0 changes this by adding native LSP support to the Go-based compiler, which may eventually replace the wrapper. The protocol is the contract; the server is the implementation. Understanding both explains how your editor knows what it knows.


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!