# Understanding typescript-go Core Functionalities: Architecture and Implementation

> Explore typescript-go's core functionalities including its modular architecture, CLI compilation, JSON-RPC API, LSP server, and high-performance incremental builds. Discover the power of native Go for TypeScript.

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

---

**typescript-go is a native Go implementation of the TypeScript compiler that provides command-line compilation, JSON-RPC API services, LSP server capabilities, and incremental build systems through a modular architecture designed for high performance.**

 typescript-go reproduces the essential toolchain features of the official TypeScript compiler (`tsc`) while exposing them as a Go library and standalone processes. This repository, `microsoft/typescript-go`, organizes its core functionalities around distinct subsystems that handle everything from parsing source code to providing editor intelligence via the Language Server Protocol.

## Command-Line Compiler (tsgo)

The **command-line compiler** serves as the primary entry point for users migrating from the Node.js-based TypeScript compiler. Located in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go), the CLI parses arguments, loads [`tsconfig.json`](https://github.com/microsoft/typescript-go/blob/main/tsconfig.json) configurations, and executes the full compilation pipeline.

The implementation delegates to [`internal/execute/tsc.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/tsc.go), which acts as the driver selecting between normal compilation and build modes. This module supports `--watch` for file monitoring, `--build` for project references, and `--init` for configuration scaffolding. Help text and option rendering are handled in [`internal/execute/tsc/help.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/tsc/help.go), ensuring parity with standard TypeScript CLI behavior.

## API Server (JSON-RPC)

typescript-go exposes compiler functionality programmatically through a **JSON-RPC/MessagePack API server**. This subsystem allows external processes to invoke the compiler without spawning new CLI instances for each operation.

The server bootstrap logic resides in [`cmd/tsgo/api.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/api.go), while [`internal/api/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/api/server.go) contains the core request handling implementation. The API supports communication over stdin/stdout or named pipes, making it suitable for integration with build systems and custom tooling. Runtime initialization accepts a `StdioServerOptions` struct to configure working directories, error logging, and default library paths.

## Language Server Protocol (LSP) Implementation

Editor integrations rely on the **LSP server**, which provides IntelliSense features including completion, diagnostics, go-to-definition, and hover information. Process startup occurs in [`cmd/tsgo/lsp.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/lsp.go), with request routing and session management implemented in [`internal/lsp/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go).

This subsystem shares the same parser and type checker as the batch compiler, ensuring consistent diagnostic output across CLI and editor environments. The LSP implementation leverages the virtual file system abstraction to handle unsaved file contents and rapid incremental updates typical in IDE workflows.

## Core Compilation Pipeline

The heart of typescript-go consists of three interconnected stages that transform TypeScript source into executable JavaScript.

### Parser and AST Generation

The **Parser** converts TypeScript source text into an Abstract Syntax Tree (AST) using algorithms defined in [`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go). Supporting utilities in [`internal/parser/utilities.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/utilities.go) handle trivia management and node creation. This implementation maintains syntax compatibility with TypeScript 6.0, producing identical AST structures for equivalent source code.

### Type Checker

**Type resolution and checking** occur in [`internal/checker/checker.go`](https://github.com/microsoft/typescript-go/blob/main/internal/checker/checker.go), which serves as the main type-checking engine. This module performs symbol resolution, control flow analysis, and type relationship validation. All compiler diagnostics and error messages originate here, feeding into the centralized diagnostics system for localization and formatting.

### Emitter

The **Emitter** translates validated AST nodes into JavaScript output and optional declaration files ([`.d.ts`](https://github.com/microsoft/typescript-go/blob/main/.d.ts)). Implemented in [`internal/compiler/emitter.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/emitter.go), this stage handles source map generation, JSX transformation, and module format conversion (CommonJS, ES modules, etc.). The emitter respects compiler options regarding target ECMAScript version and output directory structures.

## Incremental Build System

typescript-go implements sophisticated **incremental compilation** to minimize rebuild times in large codebases. The system tracks file hashes and dependency graphs through `.tsbuildinfo` files, managed primarily in [`internal/execute/incremental/program.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/incremental/program.go).

Project reference parsing, crucial for monorepo architectures, is handled by [`internal/compiler/projectreferenceparser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/projectreferenceparser.go). This subsystem determines build ordering between dependent projects and skip unchanged compilation units when inputs remain stable.

## Virtual File System and File Watching

A **Virtual File System (VFS)** abstraction layer enables typescript-go to operate across diverse environments. The implementation in [`internal/vfs/osvfs.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/osvfs.go) wraps native OS operations, while [`internal/vfs/vfswatch/watcher.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/vfswatch/watcher.go) provides file watching capabilities for `--watch` mode.

The VFS supports in-memory file systems for testing and read-only bundled libraries, ensuring the compiler functions without traditional `node_modules` installations. Watch notifications trigger selective recompilation, avoiding full project rebuilds when only specific files change.

## Practical Usage Examples

### Running CLI Compilation

Compile a project using the standard configuration file:

```bash

# Compile using tsconfig.json

npx tsgo

# Compile a single file directly

npx tsgo hello.ts

# Enable incremental watch mode

npx tsgo --watch --incremental

```

This invokes the entry point in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go), which instantiates the system implementation and executes the compilation pipeline defined in [`internal/execute/tsc.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/tsc.go).

### Starting the API Server

Integrate the compiler into Go applications using the JSON-RPC server:

```go
package main

import (
	"context"
	"log"
	
	"github.com/microsoft/typescript-go/internal/api"
	"github.com/microsoft/typescript-go/internal/bundled"
)

func main() {
	opts := &api.StdioServerOptions{
		Err:                log.Writer(),
		Cwd:                ".",
		DefaultLibraryPath: bundled.LibPath(),
	}
	srv := api.NewStdioServer(opts)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	if err := srv.Run(ctx); err != nil {
		log.Fatalf("API server failed: %v", err)
	}
}

```

This creates a `StdioServer` that listens for compilation requests and utilizes the bundled standard library definitions via `bundled.LibPath()`.

## Summary

- **typescript-go** is Microsoft's native Go port of the TypeScript compiler, offering CLI, API, and LSP server modes.
- The architecture separates concerns into distinct subsystems: parsing ([`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go)), type checking ([`internal/checker/checker.go`](https://github.com/microsoft/typescript-go/blob/main/internal/checker/checker.go)), and emission ([`internal/compiler/emitter.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/emitter.go)).
- **Incremental builds** are supported through file hashing and `.tsbuildinfo` tracking in [`internal/execute/incremental/program.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/incremental/program.go).
- A **virtual file system** abstraction enables cross-platform operation and efficient file watching via [`internal/vfs/vfswatch/watcher.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/vfswatch/watcher.go).
- The **JSON-RPC API** ([`internal/api/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/api/server.go)) and **LSP implementation** ([`internal/lsp/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go)) provide programmatic access for tooling and editor integration.

## Frequently Asked Questions

### What is the difference between typescript-go and the standard TypeScript compiler?

typescript-go is a complete reimplementation of the TypeScript compiler toolchain written in Go rather than TypeScript/JavaScript. While it maintains compatibility with [`tsconfig.json`](https://github.com/microsoft/typescript-go/blob/main/tsconfig.json) options and TypeScript language features, it runs as a native binary without Node.js dependencies, offering potentially faster startup times and different memory characteristics. The core type-checking logic in [`internal/checker/checker.go`](https://github.com/microsoft/typescript-go/blob/main/internal/checker/checker.go) produces the same diagnostics as the original compiler.

### Can typescript-go be used as a drop-in replacement for tsc?

Yes, for supported features. The `tsgo` CLI accepts the same command-line arguments as `tsc`, including `--watch`, `--build`, and `--strict` flags. However, certain advanced features and third-party compiler plugins may not yet be implemented, as indicated by the project's feature matrix. The entry point at [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) is designed to mimic `tsc` behavior closely.

### How does the file watching system work in typescript-go?

The file watcher in [`internal/vfs/vfswatch/watcher.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/vfswatch/watcher.go) monitors file system changes using OS-specific APIs and triggers incremental recompilation when source files change. When combined with `--incremental` mode, the system reads existing `.tsbuildinfo` files to determine which files require re-checking, significantly reducing compilation time for large projects during development.

### Is the LSP server compatible with all editors?

The LSP implementation in [`internal/lsp/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go) follows the Language Server Protocol specification, making it compatible with any editor supporting LSP, including VS Code, Neovim, and Emacs. The server uses the same parser and checker instances as the batch compiler, ensuring that type errors shown in editors match those produced by command-line builds.