Best Practices for Using typescript-go: Native TypeScript Compilation Guide
Use npx tsgo as a drop-in tsc replacement with --incremental for large codebases, enable --lsp for IDE support, and leverage the execute.CommandLine API when embedding the compiler in Go applications.
The typescript-go repository delivers a native Go implementation of the TypeScript compiler designed to replace tsc while maintaining compatibility with TypeScript 6.0 and future 7.0 features. Following best practices for using typescript-go ensures optimal compilation performance whether you're running command-line builds, watch mode, or integrating the compiler directly into Go-based tooling.
Architecture Overview
The typescript-go codebase follows a layered architecture that mirrors the original TypeScript compiler while leveraging Go's performance characteristics.
The CLI entry point in cmd/tsgo/main.go parses arguments and delegates to either normal compilation, LSP mode (--lsp), or API mode (--api). The command-line driver in internal/execute/tsc.go implements the core tsc compatibility layer, containing functions like CommandLine, tscCompilation, and tscBuildCompilation that parse tsconfig.json via tsoptions.ParseCommandLine and manage the compilation lifecycle.
Key architectural layers include:
internal/parser/*andinternal/ast/*– Handle lexical scanning and AST generationinternal/checker/*– Implements the full TypeScript type system and symbol resolutioninternal/execute/incremental/*andinternal/execute/build/*– Drive incremental builds and multi-project orchestrationinternal/vfs/*– Provides the virtual file system abstraction essential for LSP and in-memory compilation
The driver creates a compiler.Host using NewCachedFSCompilerHost to connect the VFS to the type-checker, then calls EmitAndReportStatistics to produce output and diagnostics.
Installation and Quick Start
Install the preview package to begin using the native compiler:
npm install @typescript/native-preview
npx tsgo --version # Verify installation
The tsgo CLI works as a direct replacement for tsc. Place a tsconfig.json at your project root, then run:
npx tsgo -p .
The driver automatically searches upward for configuration files using findConfigFile (located in internal/execute/tsc.go), matching standard TypeScript behavior.
Recommended Usage Patterns
Standard Compilation with tsconfig.json
Keep your tsconfig.json in the repository root to leverage automatic configuration discovery. The CommandLine function in internal/execute/tsc.go handles upward directory traversal to locate the configuration file, identical to the original TypeScript compiler behavior.
Avoid combining incompatible flags such as --watch with --listFilesOnly, as the driver explicitly errors with Option_watch_and_listFilesOnly_cannot_be_combined when these are used together.
Incremental Builds for Large Projects
Enable --incremental to trigger the optimized compilation path via performIncrementalCompilation (lines 83-108 in internal/execute/tsc.go):
npx tsgo -p . --incremental
This creates a .tsbuildinfo file that caches build state between runs, drastically reducing compile times for subsequent builds by reusing unchanged file information.
Watch Mode Development
For active development, use watch mode to monitor file changes:
npx tsgo -w
The watch implementation resides in createWatcher within internal/execute/tsc.go. While functional, this feature remains a prototype and may exhibit higher CPU usage with very large codebases. For production CI pipelines, prefer --incremental over --watch.
Language Server Protocol (LSP) Integration
Enable the experimental VS Code setting "js/ts.experimental.useTsgo": true for IDE support, or launch the server manually:
npx tsgo --lsp
The LSP server implementation in cmd/tsgo/lsp.go reuses the same CommandLine driver and System abstraction, ensuring consistency between CLI and IDE diagnostics. It supports full language service features including completions, quick-fixes, and real-time error reporting.
Embedding the Go API Directly
For custom build pipelines or Go-based tooling, import the internal/execute package and call the driver programmatically:
package main
import (
"github.com/microsoft/typescript-go/internal/execute"
"github.com/microsoft/typescript-go/internal/execute/tsc"
)
func main() {
// Create the default system wrapping OS file system and stdout
sys := execute.NewSystem()
// Equivalent to `npx tsgo -p ./myproject`
args := []string{"-p", "./myproject"}
// Execute compilation
result := execute.CommandLine(sys, args, nil) // nil = no testing harness
// Check exit status against tsc.ExitStatus enum
if result.Status != tsc.ExitStatusSuccess {
// Diagnostics already written to sys.Writer()
panic("Compilation failed")
}
}
The execute.System abstraction provides file system access via sys.FS(), output writing via sys.Writer(), and path utilities. Use execute.NewSystem() for real OS operations, or provide a custom implementation for virtual file testing scenarios.
Key Source Files and Implementation Details
Understanding these critical files helps debug issues and extend functionality:
cmd/tsgo/main.go– CLI bootstrap that parses--lsp,--api, and forwards toexecute.CommandLineinternal/execute/tsc.go– Central driver containingCommandLine,performIncrementalCompilation, andcreateWatcherinternal/execute/build/orchestrator.go– Coordinates multi-project builds (-bflag) for monorepo scenariosinternal/checker/checker.go– Core TypeScript type system implementationinternal/vfs/wrapvfs/wrapvfs.go– Virtual file system wrapper enabling in-memory compilationcmd/tsgo/api.go– HTTP API implementation for remote compilation services
Summary
- Install the preview via
npm install @typescript/native-previewfor immediatetsccompatibility - Use
--incrementalto leverageperformIncrementalCompilationand reduce build times in CI/CD pipelines - Place
tsconfig.jsonat the project root to ensurefindConfigFilelocates your configuration automatically - Call
execute.CommandLinewithexecute.NewSystem()when embedding the compiler in Go applications - Enable
--lspfor IDE integration, but prefer incremental builds over--watchfor production stability
Frequently Asked Questions
Does typescript-go support all TypeScript 6.0 features?
Yes, the implementation targets full TypeScript 6.0 compatibility and includes growing support for TypeScript 7.0 features. The checker in internal/checker/checker.go implements the complete type system semantics, while the parser in internal/parser/* handles all standard TypeScript and JSX syntax constructs.
How do I enable incremental compilation in typescript-go?
Pass the --incremental flag to trigger the optimized build path. The compiler creates a .tsbuildinfo file that performIncrementalCompilation in internal/execute/tsc.go uses to track file signatures and dependencies, skipping unchanged files in subsequent builds.
Can I use typescript-go programmatically in my Go application?
Yes, import github.com/microsoft/typescript-go/internal/execute and call execute.CommandLine(sys, args, nil) where sys is an execute.System interface (typically created via execute.NewSystem()). This provides the same functionality as the CLI while allowing custom file system implementations through the internal/vfs abstraction.
What is the difference between --watch and --incremental in typescript-go?
--incremental performs a one-shot compilation that writes build state to disk for faster subsequent builds, ideal for CI pipelines. --watch uses createWatcher in internal/execute/tsc.go to continuously monitor files and recompile on changes, suitable for development but currently consuming more CPU resources than the original TypeScript watch mode.
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 →