How to Contribute to the TypeScript-Go Project: A Developer's Guide
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:
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:
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 incmd/tsgo/main.gomimics thetsccommand-line interface. It parses arguments viaexecute.CommandLine(found ininternal/execute/execute.go) and delegates to subsystems. - Compiler Core: Located in
internal/compiler/program.go, this handles parsing, type-checking, emission, and incremental builds. - Language Server (LSP): Implemented in
internal/lsp/server.go, provides VS Code features like completion and diagnostics via the--lspflag. - Virtual File System: The
internal/vfs/wrapvfs/wrapvfs.gofile abstracts file access for both the compiler and LSP, enabling watch mode and in-memory files. - Code Generation: The
_scripts/generate.tsscript driveshereby 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:
hereby build
This produces built/local/tsgo. Alternatively, run go build ./cmd/tsgo directly.
Run the Test Suite
Execute the full test suite with:
hereby test
For linting and code generation, use:
hereby lint # Lints Go code
hereby generate # Regenerates Go files from TypeScript source
Contribution Scope and Guidelines
Before investing development time, review 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 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.gofiles alongside the relevant package (e.g.,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:
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:
built/local/tsgo --lsp
This invokes runLSP (defined in 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.
Summary
- Clone with submodules to get the TypeScript source required for code generation.
- Use Go 1.26+ and run
npm cito set up the build environment. - Build with
hereby buildto produce thetsgobinary inbuilt/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.gofor CLI entry,internal/compiler/program.gofor compiler logic, andinternal/lsp/server.gofor 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), 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →