Open-Source Wikis

/

TypeScript

/

Systems

/

System host

microsoft/TypeScript

System host

ts.sys is the singleton host that abstracts over the file system, console, and platform-specific behaviour. Every other compiler subsystem talks to the outside world through it.

Purpose

The compiler must run in three notably different environments:

  • Node.js — the primary host, used by tsc, tsserver, and most embedders.
  • Browser — used by the playground and online tools.
  • Custom hosts — Visual Studio's project system, plugin hosts, fuzz harnesses, the test harness.

ts.sys provides a common API for the things every host needs: read/write files, stat, watch, exit, write to stdout/stderr, get cwd, fork child processes, and similar.

Source

src/compiler/sys.ts is ~86,000 bytes and exports:

Symbol Role
System The host interface (readFile, writeFile, watchFile, args, …)
sys The default System instance — Node-backed when running on Node, undefined otherwise
getNodeSystem Builds a Node-backed System
WatchOptions, FileWatcherEventKind Watcher contracts
tryEnableSourceMapsForHost, setBlocking, setStackTraceLimit Process-level helpers

A consumer never imports Node's fs directly. Instead it reads via ts.sys.readFile(path). This means substituting an in-memory filesystem (for tests) or a virtual filesystem (for the playground) only requires swapping ts.sys.

How it works

graph TD
    Caller["scanner / parser / program / language service"] -->|abstract calls| System["interface System"]
    System --> Node["getNodeSystem (sys.ts)"]
    System --> Test["fakesHosts (harness/fakesHosts.ts)"]
    System --> Custom["custom hosts (browser, plugins)"]
    Node --> fs["Node fs / path / os / child_process"]
    Test --> VFS["vfsUtil.ts in-memory FS"]

Watch implementation is the most subtle piece. ts.sys.watchFile and ts.sys.watchDirectory take a WatchOptions that toggles between polling, native fs.watch, and chokidar-like fallbacks. The watcher options can be set per-project via tsconfig.json's top-level watchOptions field.

Key abstractions

Symbol Role
System.args CLI arguments for tsc
System.readFile(path, encoding?) Synchronous file read
System.writeFile(path, data, writeBOM?) Synchronous file write
System.fileExists(path), directoryExists(path) Stat helpers
System.getDirectories(path), readDirectory(...) Filesystem traversal
System.watchFile(path, callback, pollingInterval?, options?) File watcher
System.watchDirectory(path, callback, recursive, options?) Directory watcher
System.write(s), writeOutputIsTTY() Console writers
System.exit(code) Process exit
System.resolvePath(path), getCurrentDirectory() Path normalisation
System.realpath(path) Symlink resolution

Integration points

Entry points for modification

If you're adding a new platform behaviour (a new watcher mode, support for a new platform), edit the getNodeSystem factory in src/compiler/sys.ts and add the option to the System interface itself. The WatchOptions enum and its handling in program.ts and editorServices.ts are the places where new watch modes need to be plumbed through.

See systems/watch-and-builder for how watch options are surfaced to user-facing flags.

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

System host – TypeScript wiki | Factory