microsoft/TypeScript
Language service
The library that powers IDE features: completions, quick info, signature help, find-all-references, rename, go-to-definition, refactorings, code fixes, formatting, document highlights, and more. The language service is what tsserver exposes over its JSON protocol.
Source
The language service lives entirely under src/services/. About 168 TypeScript files totalling ~65,000 lines.
| Subdirectory | Role |
|---|---|
services/services.ts (3,622 lines) |
Top-level createLanguageService; method dispatch |
services/types.ts (75k lines effective) |
Public language-service interface types |
services/completions.ts (6,173 lines) |
Completion provider |
services/findAllReferences.ts (2,803 lines) |
Find-all-references and rename |
services/goToDefinition.ts (1,000+ lines) |
Definition / type-definition / implementation |
services/codeFixProvider.ts + services/codefixes/ |
Code-fix registry and ~80 code-fix providers |
services/refactorProvider.ts + services/refactors/ |
Refactoring registry and 16 refactorings |
services/formatting/ |
Token-level formatter |
services/signatureHelp.ts |
Parameter-hint provider |
services/symbolDisplay.ts |
"Hover" / quickInfo formatting |
services/textChanges.ts (~87k effective lines) |
High-level edit builder used by every refactor |
services/utilities.ts (~170k effective lines) |
Service-side shared utilities |
Purpose
The language service answers IDE queries against a Program. It is:
- Synchronous. Every entry point returns immediately. The client (typically
tsserver) handles cancellation via aCancellationToken. - Stateless across queries. Each call resolves the latest program, asks for what it needs, and returns. State is held by the host (file snapshots) and the program.
- Host-driven. A
LanguageServiceHost(provided bytsserveror the embedder) suppliesgetScriptFileNames(),getScriptVersion(fileName),getScriptSnapshot(fileName),getCurrentDirectory(),getCompilationSettings(),getCustomTransformers?, etc.
Key abstractions
| Symbol | Role |
|---|---|
createLanguageService(host, documentRegistry?, syntaxOnlyOrLanguageServiceMode?) |
Public factory |
LanguageService |
The query interface — ~70 methods |
LanguageServiceHost |
Filesystem-like host the service queries |
DocumentRegistry |
Cache of parsed source files shared across services |
LanguageServiceMode |
Semantic, PartialSemantic, Syntactic — controls which features are available |
Completions.getCompletionsAtPosition |
Completion entry |
findAllReferences.Core.getReferencedSymbolsForNode |
References entry |
goToDefinition.getDefinitionAtPosition |
Definition entry |
getCodeFixesAtPosition |
Code fixes |
getApplicableRefactors / getEditsForRefactor |
Refactors |
Architecture
graph TD
Host["LanguageServiceHost"] --> Service["createLanguageService"]
Service --> Program["program.ts: createProgram"]
Program --> Checker["checker.ts"]
Service --> Completions["services/completions.ts"]
Service --> Refs["services/findAllReferences.ts"]
Service --> Defs["services/goToDefinition.ts"]
Service --> Fixes["services/codefixes/*"]
Service --> Refactors["services/refactors/*"]
Service --> Format["services/formatting/*"]
Service --> Symbol["services/symbolDisplay.ts"]
Completions --> Checker
Refs --> Checker
Defs --> Checker
Fixes --> TextChanges["services/textChanges.ts"]
Refactors --> TextChangesMost providers follow the same shape:
- Snap the current
Programfrom the host. - Locate the AST node at the query position.
- Ask the checker for the relevant symbol/type/signature.
- Translate the result into the public-API shape.
textChanges.ChangeTracker is the workhorse for any feature that returns edits. It records insertions, replacements, and deletions in terms of AST nodes and emits a FileTextChanges[] at the end. Code fixes and refactors share this primitive.
DocumentRegistry
createDocumentRegistry() returns a process-wide cache of parsed SourceFiles keyed by filename, version, and CompilerOptions. When two LanguageServices share the same registry (which tsserver arranges), they avoid re-parsing the same files. The registry knows when a file's snapshot version has changed and can invalidate appropriately.
Code fixes
Code fixes are auto-suggestions targeted at specific diagnostic codes. Each fix is a small TypeScript file under src/services/codefixes/ (over 80 of them) that:
- Registers itself against one or more error codes via
codefix.registerCodeFix({ errorCodes, getCodeActions, fixIds }). - Implements
getCodeActions(context)to produce aCodeFixActionwithdescription,changes(file edits), and an optionalfixIdfor "fix all". - Optionally implements
getAllCodeActionsfor the "fix all instances of this in the file/project" path.
Examples: addMissingAsync.ts, addMissingAwait.ts, convertToAsyncFunction.ts, convertToEsModule.ts, fixUnusedIdentifier.ts, importFixes.ts (~115k effective lines on its own — auto-import is huge).
Refactors
Refactors are user-initiated transformations: extract function, extract type, convert function-to-class, move-to-file, inline variable, etc. Each lives under src/services/refactors/ and registers via refactor.registerRefactor. The provider returns a list of ApplicableRefactorInfo for the cursor position; the editor presents them as code actions; selecting one calls getEditsForRefactor which returns RefactorEditInfo with FileTextChanges.
Modes
LanguageServiceMode controls which features are available:
Semantic— full type-checking. Default.PartialSemantic— type-checks only the open file's program; cross-file features are best-effort.Syntactic— no type-checking at all; only AST-based features (formatting, brace matching, syntactic completions). Used for very fast preview workflows.
Plugins
Language-service plugins wrap a LanguageService, adding or overriding behaviour. They're loaded by tsserver based on compilerOptions.plugins in tsconfig.json or --globalPlugins. Each plugin is an npm package whose entry point exports init(modules) returning { create(info) }. The wrapped service is what tsserver then uses for that project. See src/server/project.ts.
Integration points
- Used by
tsserver(src/server/) — every editor command becomes a method call. - Used by VS Code's bundled "JavaScript" support (yes, JS too — TypeScript's JS support is the language service in
--allowJsmode). - Used by tools like tsc-alias, bundlers, and IDEs that don't speak the JSON protocol but want IntelliSense.
Entry points for modification
- New language-service feature: extend
LanguageServiceinsrc/services/types.ts, implement inservices.ts, expose throughtsserverby adding a request type tosrc/server/protocol.tsand a handler insrc/server/session.ts. - New code fix: add a file under
src/services/codefixes/and register it. - New refactor: same idea under
src/services/refactors/. - Tests for any of the above: write fourslash tests under
tests/cases/fourslash/(see how-to-contribute/testing).
See features/language-service-features and features/refactors-and-codefixes for the user-facing capabilities.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.