# TypeScript-Go Limitations: Critical Gaps in the Native Corsa Compiler

> Explore TypeScript-Go limitations including its lack of a public Go API, read-only file system, and incomplete features for Language Service, JSDoc, and declaration emit.

- Repository: [Microsoft/typescript-go](https://github.com/microsoft/typescript-go)
- Tags: deep-dive
- Published: 2026-04-25

---

**TypeScript-Go (codenamed Corsa) lacks a public Go API, enforces read-only virtual file systems that panic on write operations, runs watch mode as a non-incremental prototype, and ships with incomplete Language Service, JSDoc, and JavaScript declaration emit features.**

Microsoft's **typescript-go** repository represents a ground-up rewrite of the TypeScript compiler in Go, aiming for dramatic performance improvements in parsing and type checking. While the core compilation pipeline successfully handles standard TypeScript projects, several production-critical features remain marked as prototype or not ready. Understanding these **typescript-go limitations** is essential before adopting the tool for production builds or replacing the legacy TypeScript compiler.

## Missing Public API and Embedding Support

The most significant architectural limitation is the **absence of a public Go API**. According to the repository's [`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md) (lines 42-44), the `internal/compiler` package is not exported, meaning libraries cannot import the compiler as a dependency. The only supported entry point is the command-line interface in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go).

Attempting to embed the compiler into a Go application fails because the core logic resides in unexported internal packages:

```go
// This embedding pattern is currently impossible:
package main

import (
    "github.com/microsoft/typescript-go/internal/compiler" // ❌ Not exported
)

func main() {
    // Compile on-the-fly...
}

```

This restriction forces all integrations to shell out to the `tsgo` binary rather than using the compiler as a library.

## Virtual File System Constraints

The virtual file system (VFS) wrapper in [`internal/vfs/iovfs/iofs.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/iovfs/iofs.go) intentionally aborts on any write operation, making the current implementation strictly read-only.

### Write Operations Trigger Panics

As implemented in [`iofs.go`](https://github.com/microsoft/typescript-go/blob/main/iofs.go) (lines 90-104), the following methods panic with "not supported" errors: `WriteFile`, `AppendFile`, `MkdirAll`, `Remove`, and `Chtimes`. This design prevents the compiler from emitting files to custom file systems:

```go
package main

import (
    "io/fs"
    "os"
    "github.com/microsoft/typescript-go/internal/vfs/iovfs"
)

type readOnlyFS struct{ fs.FS }

func main() {
    ro := readOnlyFS{FS: os.DirFS(".")}
    v := iovfs.From(ro, true) // useCaseSensitiveFileNames = true
    
    // This line triggers a runtime panic:
    _ = v.WriteFile("/tmp/out.js", []byte("console.log('hi')"), 0644)
}

```

Result: `panic: writeFile not supported`.

### Case Sensitivity Handling

The VFS assumes case-sensitive path handling (lines 41-43 in [`iofs.go`](https://github.com/microsoft/typescript-go/blob/main/iofs.go)). Projects relying on Windows-style case-insensitivity must provide a custom `fs.FS` implementation that normalizes case, as the default wrapper does not handle case collisions automatically.

## Watch Mode and Incremental Build Limitations

Watch mode exists only as a **prototype** that lacks incremental re-checking. As noted in [`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md) (lines 38-40), editing any file triggers a full project recompilation from scratch. This behavior makes watch mode unsuitable for large codebases during development:

```bash

# Starts the prototype watcher

npx tsgo -w .

# Any file edit causes complete re-type-checking

```

While incremental build tracking exists for the command-line `tsgo build` mode, the watch implementation does not reuse prior type-checking results, eliminating the performance benefits typically associated with watch mode.

## JavaScript and JSDoc Compatibility Gaps

The Go port deliberately removed several legacy JavaScript and JSDoc features that were supported in the original TypeScript compiler.

### Removed JSDoc Tag Types

According to [`CHANGES.md`](https://github.com/microsoft/typescript-go/blob/main/CHANGES.md) (lines 106-112), the compiler no longer creates dedicated AST node types for `@class`, `@throws`, `@author`, and `@enum`. These tags parse only as generic `JSDocTag` nodes, breaking language service features like hover information that relied on the specific node types:

```javascript
/** @class */
function Legacy() { this.x = 0; }

```

Running `tsgo` on this file produces no class-type information in generated [`.d.ts`](https://github.com/microsoft/typescript-go/blob/main/.d.ts) files, and the Language Service cannot surface specific documentation for the `Legacy` constructor.

### Unsupported Closure Compiler Syntax

The parser no longer recognizes Closure-specific type syntax documented in [`CHANGES.md`](https://github.com/microsoft/typescript-go/blob/main/CHANGES.md) (lines 99-105). The following constructs produce syntax errors:

- Postfix nullable/non-nullable types: `T?` or `T!`
- Closure function type syntax: `function(string,string): void`
- Module namepaths

Projects using these annotations must migrate to standard TypeScript syntax before compiling with `tsgo`.

### Incomplete Declaration Emit for JavaScript

Declaration file generation ([`.d.ts`](https://github.com/microsoft/typescript-go/blob/main/.d.ts) emit) works for TypeScript sources but remains **in progress** for JavaScript files ([`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md), lines 36-38). Compiling `.js` files with declaration emit enabled produces missing or inaccurate type definitions.

## Language Service Protocol (LSP) Status

The Language Service implementation is **in progress** ([`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md), lines 41-43). While core features function, edge-case behaviors—including certain refactorings and quick-fixes—may be missing or unstable. Developers using `tsgo` for IDE support should expect occasional service interruptions or incorrect code actions compared to the production TypeScript Language Server.

## Parser and Transformer Edge Cases

The codebase contains numerous `TODO` comments indicating unfinished paths. The parser in [`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go) and transformers in `internal/transformers/` contain unhandled cases for decorator handling and error recovery. Additionally, [`internal/tsoptions/tsconfigparsing.go`](https://github.com/microsoft/typescript-go/blob/main/internal/tsoptions/tsconfigparsing.go) contains TODOs for suggestion support, indicating incomplete command-line option validation.

## Practical Examples of Current Limitations

### Successful Basic Compilation

Standard TypeScript compilation works as expected:

```bash
cat > hello.ts <<'EOF'
function greet(name: string) {
    console.log("Hello, " + name);
}
greet("World");
EOF

npx tsgo hello.ts  # Generates hello.js

```

### Attempting to Use the Go API

As confirmed by the project structure, importing the compiler fails:

```go
// Attempting to import internal packages results in a build error
import "github.com/microsoft/typescript-go/internal/compiler" 
// Go error: use of internal package ... not allowed

```

### Virtual File System Write Failure

Custom build tools cannot use the provided VFS for output:

```go
// Results in panic: writeFile not supported
vfs.WriteFile("/output/app.js", source, 0644)

```

### Watch Mode Full Rebuild

Monitoring a large project demonstrates the prototype limitation:

```bash
npx tsgo -w ./src

# Edit src/index.ts

# Observed: Full type-check re-runs (no incremental optimization)

```

## Summary

- **No Public API**: The compiler exists only as a CLI tool; Go libraries cannot import `internal/compiler`.
- **Read-Only VFS**: Write operations panic in [`internal/vfs/iovfs/iofs.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/iovfs/iofs.go); case-insensitive paths require custom implementations.
- **Prototype Watch Mode**: No incremental re-checking; every change triggers full recompilation.
- **JSDoc Regressions**: `@class`, `@throws`, `@author`, and `@enum` tags lose specialized handling; Closure syntax is unsupported.
- **Incomplete JS Support**: Declaration emit for JavaScript files and full Language Service features remain works-in-progress.
- **Parser TODOs**: Edge cases in decorators and error recovery remain unimplemented.

## Frequently Asked Questions

### Can I import TypeScript-Go as a library in my Go application?

No. The compiler API resides in `internal/` packages that are not exported. According to [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) and the repository structure, only the `tsgo` CLI binary is supported. You must shell out to the binary or fork and modify the internal package visibility.

### Does TypeScript-Go support incremental compilation in watch mode?

No. While `tsgo build` supports incremental builds, the watch mode (`-w` flag) is a prototype that recompiles the entire project from scratch on every file change. The [`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md) (lines 38-40) explicitly notes this limitation, making watch mode unsuitable for large projects.

### What JSDoc tags are unsupported in TypeScript-Go?

The compiler no longer recognizes `@class`, `@throws`, `@author`, and `@enum` as distinct AST node types, as documented in [`CHANGES.md`](https://github.com/microsoft/typescript-go/blob/main/CHANGES.md) (lines 106-112). These tags parse as generic `JSDocTag` nodes, breaking IDE features that depend on specific tag semantics.

### Is the Language Server Protocol (LSP) fully implemented?

No. The Language Service is listed as **in progress** in [`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md) (lines 41-43). While basic functionality works, advanced features like specific refactorings and quick-fixes may be missing or unstable compared to the production TypeScript compiler's language service.