This page documents the communication protocol used by tsserver — the JSON-based message format, the full set of protocol commands, and how the Session class receives, dispatches, and responds to client messages. For background on how tsserver manages TypeScript projects and the language service lifecycle, see the Project Management page. For how tsserver is initialized and fits into the overall architecture, see Language Server (tsserver).
tsserver communicates with editor clients using a line-delimited JSON protocol over stdin/stdout. Each message is a self-contained JSON object. There are three message kinds:
| Kind | Direction | Purpose |
|---|---|---|
request | Client → Server | Ask the server to perform an operation |
response | Server → Client | Reply to a specific request (success or failure) |
event | Server → Client | Unsolicited notification (e.g., diagnostics ready) |
All message definitions live in src/server/protocol.ts and are re-exported through the ts.server.protocol namespace, visible in tests/baselines/reference/api/typescript.d.ts17-18
Messages are transmitted as JSON objects. The Session class in src/server/session.ts supports two framing modes:
Newline-delimited mode (default):
Each message is a complete JSON object followed by a newline character. The session reads line-by-line from stdin and parses each line as JSON.
{"seq":1,"type":"request","command":"open","arguments":{"file":"/path/to/file.ts"}}\n
{"seq":1,"type":"response","request_seq":1,"success":true,"command":"open","body":{}}\n
Content-Length framing mode:
When ServerMode is enabled via the --serverMode flag, messages use HTTP-style Content-Length headers:
Content-Length: 72\r\n
\r\n
{"seq":1,"type":"request","command":"open","arguments":{"file":"/path/to/file.ts"}}
The Session.parseMessage() method handles both formats, detecting Content-Length headers automatically.
Sources: src/server/session.ts1-100 src/server/protocol.ts127-140
The protocol defines a base Message interface with a sequence number and type discriminator. Three subtypes extend this base:
Protocol message type hierarchy
The seq field increments for each message and allows clients to correlate responses with requests via request_seq. The success field in Response indicates whether the operation succeeded; if false, the message field contains an error description.
Sources: src/server/protocol.ts130-165 tests/baselines/reference/api/typescript.d.ts130-165
All commands are enumerated in CommandTypes in src/server/protocol.ts and reflected in tests/baselines/reference/api/typescript.d.ts49-126 Each value is a string literal that appears in the command field of a Request or Response message.
Command reference by category
| Category | Commands |
|---|---|
| File management | open, close, change, reload, saveto, updateOpen |
| Diagnostics | geterr, geterrForProject, semanticDiagnosticsSync, syntacticDiagnosticsSync, suggestionDiagnosticsSync |
| Navigation | definition, definitionAndBoundSpan, typeDefinition, implementation, findSourceDefinition, references, fileReferences |
| Completions | completionInfo, completions (deprecated), completionEntryDetails |
| Hover / Info | quickinfo, signatureHelp |
| Code fixes | getCodeFixes, getCombinedCodeFix, applyCodeActionCommand, getSupportedCodeFixes |
| Refactoring | getApplicableRefactors, getEditsForRefactor, getMoveToRefactoringFileSuggestions |
| Formatting | format, formatonkey |
| Rename / Search | rename, navto, documentHighlights |
| Navigation bar | navbar, navtree, navtree-full |
| Organize imports | organizeImports, getEditsForFileRename |
| Inlay hints | provideInlayHints |
| Call hierarchy | prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls |
| Project / config | projectInfo, configure, compilerOptionsForInferredProjects, reloadProjects, status |
| Plugins | configurePlugin |
| Misc | brace, braceCompletion, selectionRange, getOutliningSpans, todoComments, indentation, docCommentTemplate, jsxClosingTag, mapCode |
Sources: tests/baselines/reference/api/typescript.d.ts49-126 src/server/protocol.ts1-200
The Session class in src/server/session.ts orchestrates all protocol message handling:
Session.listen() reads raw bytes from stdin in a loop.Session.parseMessage() detects framing mode and parses JSON.Session.executeCommand() looks up handler in this.handlers Map.ProjectService methods, which invoke LanguageService.Session.send() serializes Response or Event and writes to stdout.The handlers Map is populated in the Session constructor, mapping each CommandTypes value to a handler method.
Session dispatch flow
Sources: src/server/session.ts1-500 src/server/editorServices.ts1-200
openNotifies the server that a file is now open in the editor. The server calls ProjectService.openClientFile() in src/server/editorServices.ts to register the file with the appropriate Project (Configured, Inferred, or External).
Request message:
The fileContent field is optional; if omitted, the server reads the file from disk. The scriptKindName can be "TS", "JS", "TSX", or "JSX".
Sources: src/server/protocol.ts200-400 src/server/editorServices.ts182-195
changeApplies an incremental text edit to an open file. The Session converts 1-based protocol positions to 0-based compiler positions before updating the ScriptInfo in src/server/scriptInfo.ts
Request message:
The edit replaces the range from (line, offset) to (endLine, endOffset) with insertString. All positions are 1-based in the protocol but stored as 0-based internally.
Sources: src/server/protocol.ts400-500 src/server/scriptInfo.ts1-100
geterr and Diagnostic EventsDiagnostics are asynchronous in tsserver. A client sends a geterr request listing files to check; the server enqueues analysis and later sends event messages of type semanticDiag, syntacticDiag, and suggestionDiag as analysis completes.
Diagnostic flow (sequence)
Sources: src/server/session.ts1-100 src/server/editorServices.ts202-212
completionInfoReturns completion candidates at a given position. The handler invokes LanguageService.getCompletionsAtPosition() and converts the result to protocol format.
Request message:
The entries array contains CompletionEntry objects with name, kind, sortText, and optional insertText fields.
Sources: src/server/protocol.ts600-800 src/services/completions.ts35-50
definitionReturns the definition location(s) for the symbol at the given position. The handler calls LanguageService.getDefinitionAtPosition() from src/services/goToDefinition.ts
Request message:
Each item includes the file path, the definition's start/end positions (1-based), and optional contextStart/contextEnd for the containing declaration.
Sources: src/server/protocol.ts800-1000 src/services/goToDefinition.ts1-100
The protocol uses 1-based line and offset (column) for all positions, represented as { line: number, offset: number }. Internally, the compiler uses 0-based character offsets. The Session class performs this conversion using getLineAndCharacterOfPosition from src/compiler/utilities.ts194 when building responses and computePositionOfLineAndCharacter from src/services/services.ts36 when processing requests.
| Coordinate space | Example |
|---|---|
| Protocol (1-based) | { line: 5, offset: 10 } |
| Compiler internal (0-based) | position = 45 |
The Session class bridges the wire protocol types defined in src/server/protocol.ts and the internal language service types in src/services/types.ts Each handler method converts between these representations.
Type conversion examples:
| Protocol Type | LanguageService Type | Conversion |
|---|---|---|
protocol.Location (1-based) | number (0-based) | computePositionOfLineAndCharacter() |
protocol.FileSpan | ts.DocumentSpan | toProtocolTextSpan() |
protocol.Diagnostic | ts.Diagnostic | formatDiagnostic() |
Mapping: protocol commands → language service methods
Sources: src/server/session.ts1-2000 src/services/services.ts212-300 src/server/editorServices.ts145-195
Beyond responses to requests, tsserver sends unsolicited event messages to the client:
| Event name | Trigger | Body type |
|---|---|---|
semanticDiag | Background semantic analysis complete | DiagnosticEventBody |
syntacticDiag | Syntactic analysis complete | DiagnosticEventBody |
suggestionDiag | Suggestion analysis complete | DiagnosticEventBody |
projectsUpdatedInBackground | Background project refresh | ProjectsUpdatedInBackgroundEventBody |
projectLoadingStart | Project load begins | ProjectLoadingStartEventBody |
configFileDiag | Error in tsconfig.json | ConfigFileDiagEventBody |
Event name constants like ProjectsUpdatedInBackgroundEvent and ConfigFileDiagEvent are defined as string constants in src/server/editorServices.ts202-212
Full component relationship
Sources: src/server/session.ts src/server/protocol.ts src/server/editorServices.ts src/server/project.ts src/server/scriptInfo.ts
Refresh this wiki