# How to Contribute to the TypeScript-Go Project: A Developer's Guide

> Learn how to contribute to the microsoft/typescript-go project. Clone the repo, install Go and Node.js, build the compiler, and submit PRs for TS 6.0/7.0 issues.

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

---

**To contribute to the typescript-go project, clone the repository with submodules, install Go 1.26+ and Node.js, build the compiler using `hereby build`, and submit pull requests that only address TypeScript 6.0/7.0 behavioral differences or crashes until the 7.0 release.**

The **typescript-go** repository contains the native Go port of the TypeScript compiler, serving as the preview for TypeScript 7. Understanding how to contribute to the typescript-go project requires familiarity with its Go-based architecture, code generation pipeline, and the specific contribution guidelines that govern the current development phase.

## Prerequisites and Repository Setup

Before writing code, you must configure the development environment correctly to handle the repository's mixed Go and TypeScript tooling.

### Clone with Submodules

The project depends on the original TypeScript source repository for code generation. Clone with submodules to ensure you have all dependencies:

```bash
git clone --recurse-submodules https://github.com/microsoft/typescript-go.git

```

### Install Dependencies

You need **Go 1.26+**, **Node.js**, and **npm** installed locally. After cloning, install the Node.js dependencies:

```bash
npm ci

```

## Understanding the Architecture

The codebase mirrors the original TypeScript compiler architecture but implements it in Go. The project consists of several key components:

- **CLI (`tsgo`)**: The entry point in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) mimics the `tsc` command-line interface. It parses arguments via `execute.CommandLine` (found in [`internal/execute/execute.go`](https://github.com/microsoft/typescript-go/blob/main/internal/execute/execute.go)) and delegates to subsystems.
- **Compiler Core**: Located in [`internal/compiler/program.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/program.go), this handles parsing, type-checking, emission, and incremental builds.
- **Language Server (LSP)**: Implemented in [`internal/lsp/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go), provides VS Code features like completion and diagnostics via the `--lsp` flag.
- **Virtual File System**: The [`internal/vfs/wrapvfs/wrapvfs.go`](https://github.com/microsoft/typescript-go/blob/main/internal/vfs/wrapvfs/wrapvfs.go) file abstracts file access for both the compiler and LSP, enabling watch mode and in-memory files.
- **Code Generation**: The [`_scripts/generate.ts`](https://github.com/microsoft/typescript-go/blob/main/_scripts/generate.ts) script drives `hereby generate`, which syncs Go source files with the TypeScript repository definitions.

## Building and Testing

The project uses `hereby` (a TypeScript build runner) to orchestrate Go commands, but raw Go commands work equally well.

### Build the Binary

Compile the `tsgo` binary using:

```bash
hereby build

```

This produces `built/local/tsgo`. Alternatively, run `go build ./cmd/tsgo` directly.

### Run the Test Suite

Execute the full test suite with:

```bash
hereby test

```

For linting and code generation, use:

```bash
hereby lint      # Lints Go code

hereby generate  # Regenerates Go files from TypeScript source

```

## Contribution Scope and Guidelines

Before investing development time, review [`CONTRIBUTING.md`](https://github.com/microsoft/typescript-go/blob/main/CONTRIBUTING.md) at the repository root. The project currently enforces a restricted contribution policy:

- **Only PRs addressing TypeScript 6.0/7.0 behavioral differences or crashes are accepted** until the 7.0 release.
- Feature work and enhancements should be postponed until after the stable release.
- All contributors must sign the Microsoft Contributor License Agreement (CLA), which the bot will prompt you to sign upon opening a PR.

## Making Code Changes

When contributing fixes, target the specific subsystems where the bugs occur.

### Working with the Compiler Core

The compiler logic resides in `internal/compiler/`. For example, [`internal/compiler/program.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/program.go) orchestrates program creation and diagnostics. If you are fixing a type-checking difference between TypeScript 6.0 and 7.0, you will likely modify files in this directory.

### Adding Tests

New functionality requires corresponding tests:

- **Go Unit Tests**: Add `*_test.go` files alongside the relevant package (e.g., [`internal/compiler/program_test.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/program_test.go)).
- **Fourslash Tests**: For language-service behavior, add tests to `internal/fourslash/tests/`. The test harness automatically translates these TypeScript-based tests into Go tests.

Example of a diagnostic test structure:

```go
package compiler

import "testing"

func TestBehavioralDifference(t *testing.T) {
    src := `let x: string = 42;`
    prog := NewProgramFromSource(src)
    diags := prog.GetDiagnostics()
    if len(diags) == 0 {
        t.Fatalf("expected diagnostic for type mismatch")
    }
}

```

### Working with the LSP Server

To test language service fixes, start the LSP server locally:

```bash
built/local/tsgo --lsp

```

This invokes `runLSP` (defined in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) at lines 17-18), which instantiates `internal/lsp.Server` and listens on stdin/stdout. You can connect to this server from VS Code using the debug configuration described in the repository's [`README.md`](https://github.com/microsoft/typescript-go/blob/main/README.md).

## Summary

- **Clone with submodules** to get the TypeScript source required for code generation.
- **Use Go 1.26+** and run `npm ci` to set up the build environment.
- **Build with `hereby build`** to produce the `tsgo` binary in `built/local/`.
- **Limit contributions** to crash fixes and 6.0/7.0 behavioral differences until TypeScript 7.0 ships.
- **Test changes** using Go unit tests or fourslash tests in `internal/fourslash/`.
- **Reference key files**: [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) for CLI entry, [`internal/compiler/program.go`](https://github.com/microsoft/typescript-go/blob/main/internal/compiler/program.go) for compiler logic, and [`internal/lsp/server.go`](https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go) for language server features.

## Frequently Asked Questions

### What types of contributions are currently accepted?

The project only accepts pull requests that fix crashes or address behavioral differences between TypeScript 6.0 and the new 7.0 version. All feature requests and general improvements should wait until after the TypeScript 7.0 stable release.

### Do I need to know both Go and TypeScript to contribute?

Yes. While the compiler is written in Go, the codebase uses TypeScript for build scripts ([`_scripts/generate.ts`](https://github.com/microsoft/typescript-go/blob/main/_scripts/generate.ts)), testing infrastructure, and the VS Code extension (`_extension/`). Understanding both languages is essential for navigating the code generation pipeline and test suites.

### How do I run the language server locally?

Build the binary with `hereby build`, then run `built/local/tsgo --lsp`. This starts a JSON-RPC server on stdin/stdout that VS Code can connect to on port 2087 by default. You can also launch this directly from the VS Code debugger using the configuration provided in the repository.

### Where are the generated Go files coming from?

The [`_scripts/generate.ts`](https://github.com/microsoft/typescript-go/blob/main/_scripts/generate.ts) script drives the `hereby generate` task, which consumes the TypeScript source repository (included as a submodule) to generate Go code for diagnostics, AST types, and other compiler structures. Always run `hereby generate` if you update the TypeScript submodule or modify generation templates.