Open-Source Wikis

/

TypeScript

/

Apps

/

tsserver

microsoft/TypeScript

tsserver

The standalone TypeScript language server. tsserver speaks a JSON command/event protocol over stdio and is hosted by editors (VS Code, Sublime, Vim, Atom, Emacs plugins, etc.) to power features like completions, find-references, inlay hints, and refactorings.

Purpose

tsserver is the long-running counterpart to tsc. While tsc is a one-shot or watch-mode batch compiler, tsserver is a stateful daemon that:

  • Tracks a graph of projects derived from tsconfig.json, jsconfig.json, and loose open files.
  • Maintains script-info per file, including buffered edits not yet on disk.
  • Lazily creates and refreshes Programs and LanguageServices per project.
  • Answers JSON commands (completionInfo, getApplicableRefactors, references, etc.) by delegating to the language service (src/services/).
  • Sends requestCompleted, event (diagnostics, project loading), and response messages back.
  • Optionally spawns typingsInstaller for ATA and watchGuard for safe recursive directory watching on Windows.

Directory layout

src/tsserver/
├── _namespaces/
├── common.ts          # Logger glue and StartInput type
├── nodeServer.ts      # Node-specific host (file watching, stdio, child processes)
├── server.ts          # 60-line main entry point
└── tsconfig.json

The bulk of the implementation actually lives next door:

src/server/
├── editorServices.ts        # 5,727 lines — the project graph manager
├── project.ts               # 3,227 lines — Project base and subclasses
├── session.ts               # 4,083 lines — JSON command dispatcher
├── scriptInfo.ts            # ScriptInfo per file
├── scriptVersionCache.ts    # Edit history + snapshots per file
├── protocol.ts              # 3,321 lines — full JSON protocol type definitions
├── packageJsonCache.ts      # tsserver-side package.json cache
├── moduleSpecifierCache.ts  # auto-import path memoisation
├── typingInstallerAdapter.ts # IPC to the typingsInstaller process
└── ... (utilities, types, etc.)

src/tsserver/ is the Node-specific entry point and host wiring; src/server/ is the cross-host server core that could in principle run in a non-Node host (and historically did, in early Visual Studio integrations).

Entry point

src/tsserver/server.ts parses a few CLI flags (--globalPlugins, --pluginProbeLocations, --useSingleInferredProject, --serverMode, --canUseWatchEvents, …), constructs a Logger, and calls startSession with a StartSessionOptions. The Node-specific host setup is in src/tsserver/nodeServer.ts (~720 lines), which:

  • Subclasses ts.sys into a ServerHost that supports event-based watching when --canUseWatchEvents is set.
  • Builds the readline-based stdio loop that frames JSON messages.
  • Spawns the typingsInstaller child process and pipes IPC events through.
  • On Windows, invokes watchGuard before enabling recursive watches on suspicious directories.
  • Wires console.log / console.warn / console.error into the server's Logger so plugins can't accidentally pollute the JSON stream.

How it works

graph TD
    Editor["Editor (VS Code, Vim, …)"] -->|JSON over stdio| Session["server/session.ts"]
    Session -->|command dispatch| ES["server/editorServices.ts"]
    ES -->|project graph| Project["server/project.ts"]
    Project -->|wraps| LS["services/LanguageService"]
    LS -->|getProgram| Compiler["compiler/program + checker"]
    Project -->|file watch + edits| SI["server/scriptInfo.ts"]
    Session -->|background events| Editor
    ES -->|ATA request| TIA["typingInstallerAdapter.ts"]
    TIA -->|child process| TI["typingsInstaller"]

A typical request lifecycle:

  1. The editor sends { "type": "request", "command": "completionInfo", "arguments": { "file": "/abs/foo.ts", "line": 7, "offset": 12, ... } }.
  2. Session.executeCommand dispatches completionInfo to a handler that resolves the file's ScriptInfo, picks the right Project, and asks the project's LanguageService for completions.
  3. The handler converts the LanguageService's CompletionInfo into the on-the-wire response shape defined in src/server/protocol.ts.
  4. The response is written back to stdout.

Diagnostics use a slightly different flow: the editor opens a file, the server schedules a debounced geterr event, and pushes semanticDiag/syntaxDiag/suggestionDiag events back to the editor as they finish.

Project graph

tsserver maintains a graph of projects: configured (ConfiguredProject), inferred (InferredProject), external (ExternalProject), and the auto-import-only AutoImportProviderProject derived per project. The graph manager is editorServices.ts. See systems/project-system for the full model.

Key abstractions

Symbol File Role
Session src/server/session.ts JSON request handler
ProjectService src/server/editorServices.ts Project graph
Project (and ConfiguredProject, InferredProject, ExternalProject, AutoImportProviderProject) src/server/project.ts Compilation contexts
ScriptInfo src/server/scriptInfo.ts Per-file editor state
ScriptVersionCache src/server/scriptVersionCache.ts Versioned text snapshots
protocol src/server/protocol.ts On-the-wire request/response types
TypingsInstallerAdapter src/server/typingInstallerAdapter.ts IPC to typingsInstaller

Integration points

  • Stdio JSON protocol — every editor talks to tsserver this way. The protocol is documented as types in src/server/protocol.ts.
  • Plugins — language-service plugins are loaded from tsconfig.json's compilerOptions.plugins or via --globalPlugins. Plugins receive a LanguageService and return a wrapped one. See systems/language-service.
  • Typings installer — the server spawns typingsInstaller.js via child_process.fork (or shares a process if configured). Communication uses ts.server.InstallTypings events.
  • watchGuard — invoked on Windows before turning on recursive directory watching to avoid known-bad paths (network drives, etc.).

Entry points for modification

For more on the language service that ultimately answers most queries, see systems/language-service and features/language-service-features.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

tsserver – TypeScript wiki | Factory