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
tsccallsts.executeCommandLine(ts.sys, ts.noop, ts.sys.args)fromsrc/tsc/tsc.ts.tsserverextendsSysteminto aServerHost(insrc/tsserver/nodeServer.ts) that adds event-based watching for editors that can push file events.- The test harness substitutes
src/harness/fakesHosts.tsandsrc/harness/vfsUtil.tsfor hermetic tests. - Browser hosts implement
Systemthemselves and provide it via the programmatic API.
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.