# TypeScript compatibility The 0.20.0 beta targets TypeScript 7.1 beta. The goal is 100% conformance; this page records the current evidence and known gaps. See the [beta release notes](releases/0.20.0.md) for installation and changes. ## Conformance tsrs is a function-by-function port of the Go implementation of TypeScript (`microsoft/TypeScript`, commit `3e9236361fa9`, TypeScript 7.1.0-beta). The Go code is the spec: any difference from it in diagnostics, their order, message text or exit code is a tsrs bug under the reference defaults, even when tsrs's output looks better. The opt-in fast preset has documented history/depth-limit differences; it does not promise exact parity for every program. See [fast-mode side effects](USAGE.md#side-effects). The [port log](../notes/typescript-623-ports.md) records all 112 commits of the source upgrade, and the [beta follow-up log](../notes/typescript-7.1-beta-ports.md) records the tag transition. Version 0.20.0 uses this pin; 0.18.0 used `b85298b6a81f`. [npm packaging](../npm/README.md#releasing) describes the release tags. The [recorded beta validation](STATUS.md#2026-10-25-0190-beta-refresh) using the upstream emit sequence matches all 13,700 error baselines, 12,998 `.types` and `.symbols` baselines each, 13,626 JavaScript/declaration baselines, 149 JavaScript maps and 156 source-map records in both Go and canonical checker histories. Checking-only harness runs have four diagnostic artifacts that disappear with the full sequence. It has also been run on a large private monorepo. See the [status log](STATUS.md) for conformance details. CI and release BOLT gates run that complete comparison in both histories and repeat selected upstream scheduling regressions at 4 and 8 checkers. Every difference, crash, timeout or empty selection fails the gate; unsupported cases are reported as skips. CI also checks generated compiler sources, SDK freshness, and all existing upstream client and local API parity cases against both compilers. The Fourslash gate requires at least 4,092 exercised groups and rejects all failing groups. [Top repository conformance](../tools/repo-conformance/README.md) compares diagnostics against pinned tsgo on 1,000 popular TypeScript repositories after qualifying changes merge into `main`. Actions reports include diffs and coverage, and warn about parity differences; incomplete runs fail. The runner is also available locally. ## What it does and doesn't do "Identical" below means identical to tsgo built from the same reference commit. Conformance counts include the completed source upgrade described above. [Differences from pinned TypeScript](DEFAULTS.md) details changed defaults, unsupported features and known parity gaps. The reference-default checker settings and fast preset are included in 0.20.0 beta. | feature | status | evidence and notes | | --- | --- | --- | | Type checking (`--noEmit`) | yes | All 13,700 error baselines and 12,998 `.types` / `.symbols` baselines match in both histories with the upstream emit sequence; flow-memo keys preserve full-width pointers on Windows and other 64-bit plain-pointer builds, keeping type-query initial states distinct (`recursiveTypesWithTypeof`, `stringLiteralsWithTypeAssertions01`); reserved high-range symbol IDs keep diagnostic truncation aligned with Go (`unique-symbol-link-id-truncation`); `using` with only `[Symbol.asyncDispose]` suggests `await using` (`usingAsyncDisposable`); JS classes eagerly check their own constructor-declared properties after their members, making implicit-any diagnostics stable for both class declarations and expressions (`flakyDiagnosticsJsClassPropertyInitializedToUndefined`); inferred type parameters are sorted by `CompareTypes` before constructing conditional type mappers (`stableTypeMapperOrdering`); merged-interface TS2320/TS2430 errors belong to the first declaration regardless of checker visit order, including when that declaration is in a skipped library (`mergedInterfaceAugmentationDiagnostics`, `mergedInterfaceDefaultLibraryDiagnostics`, `mergedInterfaceInheritanceDiagnostics`); type-argument inference caches distinct priority and variance states and reports the expected TS2345 for correlated union arguments (`inference-type-argument-variance`); static properties avoid contextual typing by their own class and spurious circularity errors (`classStaticPropertyNoSpuriousCircularityError1`); module import attribute types require string literals and reject template literals (`importAttributeType1`); pure return-type inference remains filtered by its constraint during recursive calls (`recursiveTypeInferenceReturnTypeConstraint`); the corrected `customConditions` fixture exercises both conditions and selects `browser` with package exports enabled, `index` with them disabled; empty and dot filename stems, trailing-slash type references, and NodeNext directory-import TS2834 match source 31; `typeof import()` qualifier names do not add emit-only missing-name diagnostics (`noFlakyDiagnosticsTypeofImportTypeQualifier1`, `noFlakyDiagnosticsTypeofImportTypeQualifier2`); deferred imports without namespace bindings report TS18117, including in unchecked JavaScript (`importDeferInvalidDefault`); enum computed-name expressions are checked even when their names have a grammar error, preserving expression diagnostics and reference marking (`missingIdentifierInEnumComputedNameNoFlake`, `parserComputedPropertyName16`); generic mapped-type `keyof` with renamed keys simplifies in bare and template-literal positions (`mappedTypeConstraints2`) and recursive indexed access (`mappedTypeAsClauseIntersectionConstraintIndexedAccess`); an import of an ambient module declared in the same file does not probe the filesystem for a package, including in the resolution trace (`ambientModuleImportingItselfNotResolved`); conditional-type simplification caches reading and writing separately, preserving the write-side TS2322 (`simplifiedConditionalTypeWritingCache`); JavaScript JSDoc `@extends` type arguments apply to call, mixin, element-access, parenthesized, and conditional heritage expressions, and incompatible tags name the full heritage expression (`extendsTag7`–`extendsTag14`); mapped types in JavaScript JSDoc `@extends` and `@augments` type arguments match Go without panicking (`jsdoc-heritage-mapped-type`, `jsdoc-heritage-mapped-type-diagnostics`); undefined-property widening caches by symbol identity, preserving the `undefinedPropertyDeclarationOrder` fixture and canonical `objectLiteralNormalization` baselines; top-repository comparisons still report known parity gaps and tsrs failures | | Standard library typings | yes | Source 40 imports upstream `lib.dom.d.ts` and `lib.webworker.d.ts` byte for byte, including their expanded CSS, DOM, Serial, and WebTransport declarations; the two upstream type-baseline changes match. `esnext.promise` selects `lib.esnext.promise.d.ts`; `Promise.allKeyed` and `Promise.allSettledKeyed` preserve object keys and awaited value types (`promiseAllKeyed`). Source-phase imports add `lib.esnext.modulesource.d.ts` to the `esnext` aggregate and expose `AbstractModuleSource`. Source 62 adds `lib.esnext.iterator.d.ts` to that aggregate and maps `--lib esnext.iterator` to it, exposing `IteratorObject.chunks`, `join`, and `includes` plus `Iterator.zip` and `zipKeyed`; all six new compiler variants match error, type, symbol, and JavaScript baselines; replacement libraries retain discovery order when they share a priority (`libReplacementOrder`); `es2023.intl` adds `Intl.PluralRules.selectRange` with an `Intl.LDMLPluralRule` result (`intlPluralRulesSelectRangeES2023`). Windows `noembed` executable paths use the existing OS realpath normalization before adjacent-library lookup (`test_noembed_executable_realpath_uses_compiler_path_spelling` and the `npm_lib_path` CLI tests; Windows runtime validation pending). | | Source-phase imports | yes | `import source name from "module"` and `import.source("module")` match the source-24 Go compiler on all 31 new conformance variants, including module restrictions, grammar diagnostics, typing, emit and intentionally skipped module resolution. The new Fourslash cases add 12 passing named outcomes for auto-import, definition, references and organize-imports; sync and async Node API cases pass. | | Multithreaded checking, `--singleThreaded`, `--pretty`, `--listFiles`, `--listFilesOnly` | yes | Four checkers and Go's assignment/history by default. `--fast` uses every core up to 16, then at least 16 or half the cores, at most 32 checkers, capped for small programs; build mode uses four in both modes. Fast mode enables work stealing, file splitting and eligible module affinity ([experiment note](../notes/perf-icount-hillclimb.md)) | | Performance preset (`--fast`, `TSRS_FAST=1`) | opt-in | Shipped in the 0.20.0 beta npm packages, including `@tsrs/wasm`. Enables adaptive checker counts, canonical history/caches, lazy members and eligible memory-saving modes; default compilation uses pinned TypeScript's checker settings. Known history/depth-limit cases can change diagnostics and exit status; resource use and counters can change, and incompatible incremental caches are rejected. Checking options stay as configured. The CLI flag overrides `TSRS_FAST`; explicit feature options override the preset. `--lsp` and `--api` processes that inherit `TSRS_FAST=1` use lazy members and canonical history. Benchmark runners explicitly enable the preset, including CodSpeed ([methodology](../bench/README.md)). Direct smoke checks cover environment/CLI precedence, response files and incremental mode changes; watch and cache-policy coverage exercises fast mode ([usage and side effects](USAGE.md#performance-options)) | | Compiler statistics (`--diagnostics`, `--extendedDiagnostics`) | yes | Since 0.17.0, timings are collected only when requested; config-read timing requires the flag on the command line. Internal flow-memo, lazy-list, filesystem-call and reclaimed-page counters have been removed ([debugging](DEBUGGING.md)) | | Memory target (`--maxMemory `) | `--noEmit` checks, opt-in | Replaces the largest checker after crossing the target, trading CPU for memory; testdata/regressions identical with a checker retired after nearly every file, also in poison mode ([experiment note](../notes/mem-recycle-checkers.md)) | | Lazy declaration member parsing | fast preset or `TSRS_LAZY_DTS=1`, eligible CLI modes | Requires `skipLibCheck` or `noCheck`; enabled in batch and incremental compilation, and non-watch `--build` when every built project skips declaration checking. `TSRS_LAZY_DTS=0` overrides the preset. Mixed-project bind diagnostics and incremental outputs are covered by `lazy_dts_build` CLI tests; historical #722 measurements saved 33–39% peak RSS ([measurements](../notes/mem-lazy-dts-build.md)) | | Diagnostics across checker counts and file orders | TypeScript's sensitivity is preserved by default | The upstream compiler itself can change diagnostics when checker count or file order changes. Fast mode removes selected dependencies; known upstream cases remain. Every upstream case also runs in fast mode; [selected upstream regressions](../testdata/checker-determinism.txt) repeat with work stealing and seeded assignments at 4 and 8 checkers. The [determinism task](../tasks/determinism/README.md) compares all benchmark projects against committed single-threaded npm tsgo snapshots from the Cargo-pinned release, with Go defaults and fast-mode locality/unnamed scheduling at four and all available CPU checkers, three repetitions each, plus three seeded random assignments per count; local macOS validation passed all 456 comparisons across 19 projects at 4 and 12 checkers, plus 912 regression invocations across all 48 fixtures under the optimized and seeded random schedules at 2 and 4 checkers; merged-interface TS2320/TS2430 ownership is stable at the first declaration across checker assignments; some other diagnostics still depend on file order through tsgo's own logic ([experiment note](../notes/open-history-dependence.md)); reference-default comparisons use `--fast false`, no per-feature overrides, and matching checker counts | | JavaScript emit | yes | all of tsgo's transforms; 13,626 `.js` baselines pass, 0 fail; decorated anonymous class declarations without `export default` receive generated names even when invalid, so their ES2022 decorator emit succeeds (`anonymousClassDeclarationWithClassDecorator`); decorated classes with duplicate static and instance private names preserve invalid declarations through ES2015/ES2022 lowering without a crash (`esDecorators-classDeclaration-methods-staticPrivate`); decorated class declarations with private self-references preserve their inferred names and computed-field initialization through ES2015/ES2022 lowering (`esDecorators-classDeclaration-setFunctionName`, `esDecorators-classDeclaration-setFunctionNameComputedField`); malformed destructuring assignment elements continue through class-field and decorator transforms without crashing, matching all seven new JavaScript baselines; decorator metadata traversal keeps object-literal methods and accessors outside the enclosing class's parent context (`decoratorMetadataObjectLiteralMethodNoCrash`); when a later relative import lowers a symlinked package file's `node_modules` depth, its transitive imports are revisited and emitted (`symlinkedPackageReachedRelativelyIsNotExternalLibrary`); under `verbatimModuleSyntax`, a default import retains the declaration while an emptied type-only named-import list is omitted, but a source-written `{}` is preserved (`verbatimModuleSyntaxDefaultImportTypeOnlyNamed`); function-local loops avoid spurious export assignments for shadowed names while file-level loops still update hoisted `var` exports (`commonjsExportShadowedInFunctionLoop`); a CommonJS `with` statement emits an empty statement when its nested export declaration is removed (`withStatementCommonJsEmit`); named function/class expressions avoid spurious emit diagnostics (`noFlakyDiagnosticsExpressionNameShadowedInBody1`); `typeof import()` qualifiers do not retain a same-named unused import (`importElisionTypeofImportTypeQualifier`); downleveled static blocks substitute class `this` while nested regular functions retain their own receiver (`classStaticBlock29`) | | Declaration emit (`.d.ts`) | yes | part of the `.js` baselines; chained merged export aliases and `export =` classes with separate type exports retain accessible class identities, including private members (`declarationEmitExportAssignmentWithTypeExports`, `declarationEmitTwoMergedExportAliases`); recursive array and tuple types report cyclic serialization errors when unnameable, preserve named aliases, and retain finite deep containers (`recursiveContainerDeclarationSerialization`); late expando alias exports preserve earlier namespace exports (`declarationEmitLateExpandoAliasAddsExports`); cyclic inferred structures and serializer depth truncation report declaration errors (`declarationEmitUnserializableTypes`); reverse-mapped properties and index signatures retain inferred types for downstream consumers, with bounded recursive expansion (`reverseMappedDeclarationSerialization`); alternate named, aliased, star, and `export =` re-export paths preserve declaration import names and source-file order (`declarationEmitAlternativeContainingModules`); constructor-assigned JavaScript properties retain JSDoc `@private`, `@protected`, and `@readonly` modifiers, including on static properties (`jsDeclarationEmitThisPropertyJSDocModifiers`, `jsdocAccessibilityTagsDeclarations`, `jsdocReadonlyDeclarations`); `package.json` exports are used in declarations only when the importing file can reach the package through `node_modules`, so inaccessible transitive types report TS2883 instead of emitting unresolvable bare imports (`declarationEmitUnreachablePackageExports`); `--stripInternal` replaces an elided type-alias right-hand side with `any` instead of aborting declaration emit (`declarationEmitStripInternalTypeAliasRHS`); JavaScript `@extends` generic arguments on expression heritage carry through declaration emit (`extendsTag7`, `extendsTag10`), while `extends null` remains unaugmented (`extendsTag14`) | | Source maps, declaration maps | yes | 149 `.js.map` and 156 `.sourcemap.txt` baselines pass, 0 fail; empty `sourceRoot` is omitted, and source lookup handles URL roots, empty/null sources, invalid indices and duplicate paths | | Incremental builds (`.tsbuildinfo`) | yes | Source 108 clears deleted files from pending state and invalidates retained default-library diagnostics when a global file is removed; all 14 new upstream deletion scenarios pass across checker modes and `noCheck`/`noEmit` combinations. Recursive tagged-tuple types retain their semantic diagnostics across comment, union and no-change rebuilds, including after build-info deletion; the nine-edit upstream scenario passes the Rust replay. Nested triple-slash references resolve from the containing source file before project-reference redirects. Default settings use Go's build-info format. Fast mode records its performance settings and, for canonical CLI diagnostics, a slot signature. Switching history or lazy-member settings rejects incompatible caches and requires a fresh check ([details](EMIT.md#json)) | | `--build` (project references) | yes | 189 of 192 `tsbuild` and 191 of 223 `tsc` scenario baselines pass; the failures are CLI commands tsrs doesn't port (`--help`, `--init`, …). Builders now take full and selected project graphs in stable dependency-depth order, while status reports retain build order (upstream `TestBuildScheduling`; Rust full/selected/references-only graph regression). 0.17.0 frees each project's program once it is built: a synthetic 7,500-project graph peaks at 4.8 GB at `--builders 64 --checkers 1`, where it aborted with the arena range exhausted before ([experiment note](../notes/mem-build-free-programs.md)). Source fixes #696 by reclaiming package-cache entries with their final cache generation and limiting outstanding ordinary-build frees to four. Build diagnostics detach their source files before program regions are freed, retaining text for related information and pretty summaries without retaining the full program (`build_free_programs`, #768) | | Multi-package emit | yes | Run on a large private monorepo | | Content mappers (`.vue`, `.svelte`, `.astro` via `contentMappers`) | CLI and `-b`: yes. Language server: no | Mapper manifest defaults and per-project `outputExtensions` now change expected external output and declaration paths and rewrite imports in JavaScript and declarations, with unsafe rewrites and output collisions diagnosed. Direct compiler and incremental/build tests pass against source-79 Go; all 9 earlier content-mapper scenario baselines remain identical. The compiler harness still skips 25 content-mapper fixture files (including all 10 new output-extension files and their 13 variants). The language server validates `custom/setContentMapperContributions`, including mapper output extensions, and forwards contributions to the project session; mapper execution remains unported ([experiment note](../notes/contentmappers.md)). | | Language server (`--lsp -stdio`) | yes | 4,092 of 4,562 fourslash groups pass through the [Go subprocess runner](../tools/go-fourslash/README.md); the two new source-79 mapper project-reference groups are skipped because mapper callbacks cannot cross that runner's process boundary. LSP `custom/initializeAPISession` returns a private API pipe over the language server's projects and unsaved files, with session ownership and shutdown covered by API and socket tests. Passing groups include quoted module specifiers in auto-import fixes and snippets, the inferred-project workspace-symbol refresh (`TestWorkspaceSymbolNewInferredProject`), project-state baselines, typed JSDoc `@param` tags recognized by object-binding completion context, reverse-mapped type quick info, source-phase import navigation/organization, empty/dot-stem file rename, CSS-module auto-imports with relative and rooted ambient names, JSX auto-import action titles that name a different required symbol, and template-string formatting across multiline tokens; top-level imports are excluded from document symbols while their JSDoc typedefs and callbacks remain; eight use Go-built fixture setup. Non-file document URIs retain path/query/fragment identity; completion resolution validates file names; project watchers preserve path spelling and session shutdown drains background work. CI and release workflows use the Go runner from 0.17.0; the translated Rust suite has been removed | | Node API sessions from the language server (`custom/initializeAPISession`) | yes | an editor extension's `API.fromLSPConnection` client queries the server's projects, unsaved editor text included, through `getCurrentLanguageServerSnapshot`, and can build, build references, clean and dispose build orchestrators using the host filesystem; Go's session_apistate_test.go is ported (`tsrs_api`), plus language-server-to-API socket, build and shutdown tests (`tsrs_lsp`, Unix only); no upstream client suite covers it. Sessions listen on a private Unix socket or a Windows named pipe ([Node API](NODE_API.md)); pending accepts survive LSP EOF/context cancellation as in pinned Go, leaving the Unix socket directory behind ([known gap](LSP.md#known-gaps)) | | VS Code project-local SDK (`tsdk/`) | macOS and Linux | The 0.20.0 beta includes an executable `tsdk/tsgo` that delegates to the existing npm launcher. Set `js/ts.tsdk.path` to `./node_modules/tsrs/tsdk` to use the project's installed version ([editor setup](LSP.md#editor-setup), issue #661). Packed-consumer checks cover executable mode, binary lookup, CLI arguments and exit status, the pinned extension's resolver, and an LSP initialize/shutdown exchange. Windows SDK discovery requires a native `.exe`, so this Node launcher does not provide a Windows SDK. | | VS Code API module loader (`vscode`) | yes | Source 50 exports the upstream `createTypeScriptModuleLoader` and public SDK types; source 58 promotes its subpath to `tsrs/vscode`. Given a selected package's `package.json`, the loader resolves a `typescript/*` specifier through that package's own exports, including a selected `tsrs` package. The package build and Node tests cover the runtime; the type-only consumer smoke test covers its declarations. | | Bundled VS Code extension and response middleware API | no | tsrs ships the LSP server, not the TypeScript VS Code extension. Source 28 adds `registerLspMiddleware` to that extension's client API, and source 50 adds selected-SDK events, installation identity and restart handling; those extension lifecycle behaviors have no tsrs counterpart. `vscode` exports the loader and interface types, but no extension runtime. | | Allocation profiling (`alloc-profile` build) | no | the counting allocator, heap sampler, reachability census and checker heap census have been removed; `TSRS_MEM_SPLIT` and `TSRS_ARENA_POISON` remain ([debugging](DEBUGGING.md)) | | Automatic type acquisition, profiling (language server) | no | not ported | | Telemetry (language server) | request failures only | Request-failure events, including flaky diagnostics, are sent when enabled; performance and project telemetry are not ported ([details](DEFAULTS.md#language-server)) | | Node API server (`--api`) | yes, with gaps | The [recorded beta SDK suite](../npm/sdk/METHODS.md) passes 968/968 tests on both compilers, with successful responses for 170 of 177 methods; concurrent sync callbacks answer nested requests in stack order (source 60); async `Snapshot`, `Program`, and `BuildOrchestrator` return their disposal Promises from `[Symbol.asyncDispose]`, so `await using` waits for cleanup; `createSourceFile` rejects empty names and resolves relative names against the session directory; npm API paths preserve case and non-file URI identity; source 31 reports enum `caseSensitivity`, omits inferred-project `configFileName`, resolves raw compiler-option paths against the server directory, rejects empty document identifiers, and normalizes relative callback `realpath` results; a program created through the API with project references and no config file reports reference errors as locationless program diagnostics (`create_program_reports_non_composite_project_reference_without_config_file`, source 46); static and callback module resolutions skip disk-layout import rewrite diagnostics (`custom_module_resolutions_skip_disk_layout_import_diagnostics`, source 47); project checker methods expose merged symbols, declaration/node symbols, and merged parents, including late-bound computed members, distinct from raw binder-symbol access where appropriate; `getSymbol(decl)` returns a cached file-owned binder symbol for a live remote declaration and rejects stale or symbol-free declarations; snapshot creation/update accepts per-snapshot `userPreferences` and `prepareAutoImports`; completions with `includeSymbol` require that same prepared snapshot so returned symbol handles remain valid; source 58 removes duplicate `rootFiles` and `compilerOptions` from the project wire response in favor of `parsedCommandLine` and moves node-insertion formatting under the language service; request-filesystem Go fixtures exercise the production implementation in default tests; cached circular config inheritance reports TS18000 without listing a config as its own extension (source 82); no profiling requests; source 101 makes Unix `--pipe ` create a private 0700 directory with a 0600 `/socket` and restricts Windows named pipes to the current user ([Node API](NODE_API.md)); source 102 makes sync SDK generator instances single-use across batch calls, rejecting reuse even after completion; source 109 enables sync and async timing collection through `TS_API_TIMING_DIR`, writes one JSON snapshot on close, and keeps sync callback failures sticky so the channel cannot read out-of-sequence responses; LSP API sessions support `getCurrentLanguageServerSnapshot` and release client-owned projects, files and synthetic programs on disconnect; unknown `moduleDetection` numbers use the default detection behavior ([option parsing gaps](DEFAULTS.md#option-parsing-edge-cases)) | | npm packages (`tsrs`, `@tsrs/-[-]`) | yes | The 0.20.0 beta uses `0.20.0-ts7.1.0-beta` for all nine packages (main, seven native platforms and WebAssembly), built from `3e9236361fa9`. The main package exports the upstream `tsconfig` and `jsconfig` JSON schemas, generated `CompilerOptions` types, and beta API subpaths (`sync`, `async`, `fs`, `path`, `proto`, `ast`, `vscode`). Native packages ship the default libraries beside the binary; npm builds use `noembed`, while default Cargo and WebAssembly builds retain embedded libraries. Binaries report TypeScript `7.1.0-beta` so `.tsbuildinfo`, `typesVersions` and `--version` agree with the matching reference package. See [packaging and release tags](../npm/README.md). | | WebAssembly (`@tsrs/wasm`) | yes | single-threaded; renamed to `@ts-rs/wasm` in 0.12.0 and `@tsrs/wasm` in 0.16.0; byte-identical to native `--singleThreaded` on a 2,000-case conformance sample ([experiment note](../notes/wasm-build.md)); host paths above 128 MiB use direct memory views to avoid a deployed Workers `subarray` failure that silently hid files (issue #718; hosted Effect comparison) | | Browser playground | yes | [hosted on Void](https://tsrs-playground.void.app), also available as a [local/static build with the vendored official TypeScript Playground page and styles](../playground/README.md): tsrs WASM checking and emit, virtual files, errors, JS/declarations, examples, Run/Logs, share links and compatible plugins; pinned visual-source integrity, native-equivalence integration checks and local/hosted production browser checks. Basic editing only: no semantic autocomplete/hover, AST/type inspection, inlay hints, or automatic package type acquisition | | Options TypeScript 7 removed (ES5 target, AMD/UMD/System, `baseUrl`, …) | rejected, as in tsgo | same TS5102 / TS5108 errors | | Network filesystem paths | rejected, as in tsgo | Source 104 refuses UNC (`//server`), Win32 device (`//?/...`) and NT object (`/??/...`) roots before OS-backed filesystem access, file/directory watches, config extends and paths, project references, and triple-slash references. Rejected config and reference paths report TS5116 (`networkPathReferences` and six config API baselines); `/??/*.ts` remains a valid local file-spec wildcard. Profiling remains unimplemented. | | `--watch`, `-b --watch` | yes; Linux and macOS (Windows: exits with "not supported") | The seven former watch-tuning flags (`watchInterval`, `watchFile`, `watchDirectory`, `fallbackPolling`, `synchronousWatchDirectory`, `excludeDirectories`, `excludeFiles`) now report the same unknown-option diagnostics as tsgo. 39 of 42 `tscWatch` and all 65 `tsbuildWatch` scenario baselines pass; the three failures are `--help` and `--init`. Watches with inotify on Linux (tsgo uses fanotify where the kernel allows it, inotify otherwise) and FSEvents or kqueue on macOS. Controlled descriptor-reuse and overlapping-watch cases verify kqueue closes only its current owned descriptors; controlled native batches and real filesystem delivery cover FSEvents write settling. On Linux a cycle starts when the writer closes the saved file, where tsgo starts at the first write (often the truncation) and checks a half-written file. A watch session frees each replaced program and each parsed file version nothing refers to any more (notes/watch-memory.md), and `-b --watch` reuses parsed files whose text is unchanged; tsgo reparses every file each cycle. Ctrl-C ends the session | | `--init`, `--showConfig` | no | exits with "not supported"; `--help` prints a short usage | | `--locale` | ignored | messages are English only. The source-99 catalogs for `pt-BR`, `tr-TR`, and `zh-TW` and source-61 catalogs for ten other locales, with their gzip archives, are preserved and validated but not loaded by the compiler; the upstream OneLoc automation is outside this repository ([diagnostic localization data](../tools/gen-diagnostics/README.md)) | | `--generateTrace` | no | warns "Failed to start tracing" (tsgo's message when it can't write a trace) and type-checks as without the flag | | Ctrl-C, SIGTERM | `--lsp` and `--api`: yes. Command line: stops at once | the language server exits with status 1 ("context canceled"), the API server with status 0 after the next message or EOF, as in tsgo. tsgo's command line catches the signals too but finishes a non-incremental run anyway; tsrs keeps their default action so a check can be interrupted. Windows: default action everywhere | | Prebuilt binaries | yes | The 0.20.0 beta release pipeline targets macOS arm64/x64, Linux x64/arm64 (glibc and musl), and Windows x64. Intel macOS (`@tsrs/darwin-x64`, `x86_64-apple-darwin`) and Windows x64 are additions since 0.18.0. The Intel macOS release job uses `macos-15-intel` for native PGO training and installed-package CLI/Node API smoke tests, and publishing requires its artifact; the Windows CLI returns through the C runtime so PGO profiles can be written, with native Windows training and Linux BOLT validation still pending |