This page documents how tsserver manages project lifecycles through ProjectService, the three primary project types (ConfiguredProject, InferredProject, ExternalProject), and how individual files are tracked via ScriptInfo. It covers the file-open/close lifecycle, project structure updates, and how each project is associated with a LanguageService instance.
For the tsserver protocol and how clients communicate with these projects, see page 5.1 For Automatic Type Acquisition (ATA), which runs alongside project management to install @types packages, see page 5.3
When an editor client connects to tsserver, it does not create language services directly. Instead, it interacts with ProjectService, which decides which project each open file belongs to, creates or tears down projects as needed, and keeps each project's compiler state up to date. A project is the unit of compilation inside tsserver: it owns a Program, a LanguageService, and a set of ScriptInfo objects representing its source files.
Project management lives in several primary files:
| File | Role |
|---|---|
src/server/editorServices.ts | ProjectService class — central coordinator and state manager. |
src/server/project.ts | Project base class and concrete implementations (ConfiguredProject, etc.). |
src/server/scriptInfo.ts | ScriptInfo — per-file state tracked by ProjectService. |
src/server/session.ts | Session — bridges protocol messages to ProjectService calls. |
Sources: src/server/editorServices.ts145-195 src/server/project.ts153-195
Five project kinds are distinguished by the ProjectKind enum in src/server/project.ts src/server/project.ts184
Project Kind Summary
| Kind | Class | Trigger |
|---|---|---|
Configured | ConfiguredProject | A tsconfig.json or jsconfig.json was found. |
Inferred | InferredProject | No config file; editor opened a loose file. |
External | ExternalProject | Client explicitly created the project via protocol. |
AutoImportProvider | AutoImportProviderProject | Background project for auto-import from node_modules. |
Auxiliary | AuxiliaryProject | Internal auxiliary use (e.g., nightly features). |
Backed by a tsconfig.json (or jsconfig.json). ProjectService searches ancestor directories for a config file when a file is opened. The parsed ParsedCommandLine from the config drives the compiler options and the file inclusion list src/server/editorServices.ts153 File system watchers monitor the config file and any wildcard include/exclude patterns.
Created for files that have no discoverable tsconfig.json. Each such file group is placed in an inferred project. The compiler options are either default values or those supplied by the client via the setCompilerOptionsForInferredProjects protocol message src/server/editorServices.ts162
Created on behalf of the editor client, which supplies the full file list and compiler options via the openExternalProject protocol commands src/server/editorServices.ts159 The client is responsible for calling closeExternalProject when the project is no longer needed.
A background project that shadows a root project. It expands the set of available symbols for auto-import completions by including packages present in node_modules that are not in the root project's compilation src/server/editorServices.ts149
Sources: src/server/project.ts153-195 src/server/editorServices.ts145-168
Project class hierarchy
Sources: src/server/project.ts153-195
ProjectService (defined in src/server/editorServices.ts) is the single stateful object that owns all projects and all open files.
| Field | Purpose |
|---|---|
openFiles | All currently-open files with their project root hint. |
configuredProjects | Active configured projects keyed by config file path. |
inferredProjects | All active inferred projects. |
externalProjects | All active external projects. |
filenameToScriptInfo | All known ScriptInfo objects. |
documentRegistry | Shared registry that avoids re-parsing source files. |
The documentRegistry is shared across all projects so that SourceFile objects are reused when the same file appears in multiple projects src/server/editorServices.ts30-31
ProjectService raises events that Session forwards to the editor client:
| Constant | Value | When |
|---|---|---|
ProjectsUpdatedInBackgroundEvent | "projectsUpdatedInBackground" | Background project graph refresh completed. |
ProjectLoadingStartEvent | "projectLoadingStart" | Project is about to load files. |
ProjectLoadingFinishEvent | "projectLoadingFinish" | Project finished loading. |
LargeFileReferencedEvent | "largeFileReferenced" | A file exceeds maxFileSize (4 MB). |
ConfigFileDiagEvent | "configFileDiag" | Diagnostics in a tsconfig.json. |
Sources: src/server/editorServices.ts202-212
ScriptInfo (in src/server/scriptInfo.ts) represents a single file as seen by ProjectService. It is the bridge between the raw file on disk and the IScriptSnapshot that the compiler consumes.
Key responsibilities of ScriptInfo:
ScriptKind (TS, JS, TSX, JSX, JSON, …).containingProjects) that include this file.IScriptSnapshot used by the compiler host.Sources: src/server/scriptInfo.ts186
Data flow: from open-file request to LanguageService
Sources: src/server/editorServices.ts145-212 src/server/project.ts153-195 src/server/session.ts190 src/server/scriptInfo.ts186
When the editor sends an open request, Session calls ProjectService.openClientFile.
ProjectService looks up or creates a ScriptInfo.ProjectService walks ancestor directories looking for tsconfig.json.project.updateGraph() is called to refresh the Program src/server/editorServices.ts104When the editor sends a close request, Session calls ProjectService.closeClientFile.
ScriptInfo is marked as not open; its content reverts to being read from disk.ProjectService may delete orphaned inferred projects.The maxFileSize limit (4 MB, set in editorServices.ts src/server/editorServices.ts200) prevents tsserver from loading extremely large files into memory.
Sources: src/server/editorServices.ts198-200 src/server/project.ts153-195
ProjectService uses file system watchers (via ServerHost) to detect changes and schedule project graph updates.
| What is watched | Triggers |
|---|---|
tsconfig.json | Compiler options changed; re-parse config and rebuild. |
| Wildcard include | Files added/removed matching include/exclude globs. |
| Individual source | File content changes when file is not open in editor. |
Changes are batched using ThrottledOperations src/server/editorServices.ts192
Sources: src/server/editorServices.ts120-143 src/server/project.ts153-195
Each Project instance creates exactly one LanguageService.
Project itself implements LanguageServiceHost src/services/services.ts213DocumentRegistry is passed in so SourceFile ASTs are shared src/services/services.ts39Project host protocol
Sources: src/server/project.ts153-195 src/services/services.ts212
Sources: src/server/editorServices.ts198-212 src/server/project.ts153-195 src/server/scriptInfo.ts186
Refresh this wiki