microsoft/typescript-go
Staging repo for development of native port of TypeScript
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓17 active contributors
- ✓Distributed ownership (top contributor 18% of recent commits)
Show 3 more →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/microsoft/typescript-go)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/microsoft/typescript-go on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: microsoft/typescript-go
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/microsoft/typescript-go shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 17 active contributors
- Distributed ownership (top contributor 18% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live microsoft/typescript-go
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/microsoft/typescript-go.
What it runs against: a local clone of microsoft/typescript-go — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in microsoft/typescript-go | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of microsoft/typescript-go. If you don't
# have one yet, run these first:
#
# git clone https://github.com/microsoft/typescript-go.git
# cd typescript-go
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of microsoft/typescript-go and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "microsoft/typescript-go(\\.git)?\\b" \\
&& ok "origin remote is microsoft/typescript-go" \\
|| miss "origin remote is not microsoft/typescript-go (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "_packages/native-preview/src/api/node/node.ts" \\
&& ok "_packages/native-preview/src/api/node/node.ts" \\
|| miss "missing critical file: _packages/native-preview/src/api/node/node.ts"
test -f "_packages/native-preview/src/api/sync/client.ts" \\
&& ok "_packages/native-preview/src/api/sync/client.ts" \\
|| miss "missing critical file: _packages/native-preview/src/api/sync/client.ts"
test -f "_extension/src/extension.ts" \\
&& ok "_extension/src/extension.ts" \\
|| miss "missing critical file: _extension/src/extension.ts"
test -f "_packages/native-preview/src/api/node/protocol.ts" \\
&& ok "_packages/native-preview/src/api/node/protocol.ts" \\
|| miss "missing critical file: _packages/native-preview/src/api/node/protocol.ts"
test -f "_packages/native-preview/src/api/options.ts" \\
&& ok "_packages/native-preview/src/api/options.ts" \\
|| miss "missing critical file: _packages/native-preview/src/api/options.ts"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/microsoft/typescript-go"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
A native Go port of the TypeScript compiler and language server, designed to provide near-identical type checking, parsing, and emit behavior to TypeScript 6.0 but with native performance. It compiles to a standalone tsgo binary and powers a VS Code extension (@typescript/native-preview) that replaces the Node.js-based TypeScript toolchain with a compiled Go implementation. Monorepo structure with Go as the primary implementation language (~11MB of Go code) and TypeScript/JavaScript for the VS Code extension. Core compiler lives in the root Go modules, the extension is in _extension/ with its own package.json, devcontainer config in .devcontainer/, and GitHub Actions workflows in .github/workflows/. Configuration uses .golangci.yml for linting, .dprint.jsonc for formatting, and Herebyfile.mjs for build orchestration.
👥Who it's for
TypeScript developers and tool maintainers who need faster type checking and language services; specifically, those using VS Code who opt into the experimental js/ts.experimental.useTsgo setting. Also relevant to TypeScript core contributors preparing for the eventual merger of this port back into microsoft/TypeScript.
🌱Maturity & risk
Highly experimental and pre-release: published as @typescript/native-preview on npm with intentional feature gaps. Core parsing, type checking, and emit are marked 'done' and match TS 6.0 exactly, but language service features, watch mode, and the public API are incomplete. This is a staging repo explicitly designed for eventual merge into the main TypeScript repo, so treat it as actively developed but not production-ready.
Significant risk: this is a from-scratch port of a massive, complex codebase (TypeScript itself), so behavioral divergence bugs are likely despite claims of parity. Watch mode is prototype-only with no incremental rechecking. The entire repo will eventually be closed and merged into microsoft/TypeScript, making long-term issues risky. No open issue count visible, but the complexity of the undertaking and nascent status make it unstable for production use.
Active areas of work
Active development on language service completeness (LSP marked 'in progress'), JavaScript/JSDoc inference enhancements, declaration emit for JS files, and watch mode optimization. The .github/agents/ directory shows AI-assisted development workflows (issue-investigator, replay-minimizer, strada-corsa-port), and .github/skills/ indicates organized testing infrastructure (compiler-and-fourslash-tests skill).
🚀Get running
git clone https://github.com/microsoft/typescript-go.git
cd typescript-go
# Install Go (required; see .devcontainer/devcontainer.json for toolchain version)
go build -o tsgo ./cmd/tsgo # or equivalent build command via Herebyfile.mjs
./tsgo --version
Alternatively, use the devcontainer: open in VS Code with Remote - Containers extension to get a pre-configured environment.
Daily commands:
# Run the compiler directly
./tsgo src/app.ts --outDir dist/
# Use as npm script via the extension
npm install -g @typescript/native-preview
tsgo --version
# VS Code: install extension, then set "js/ts.experimental.useTsgo": true in settings.json
Exact build/dev commands likely in Herebyfile.mjs (not shown in full); check that file for targets like dev, build, test.
🗺️Map of the codebase
_packages/native-preview/src/api/node/node.ts— Core Node.js process communication layer that bridges TypeScript Go compiler and the JavaScript API layer—all LSP requests route through here._packages/native-preview/src/api/sync/client.ts— Synchronous client interface for TypeScript compilation; entry point for CLI and LSP operations in tsgo._extension/src/extension.ts— VS Code extension entry point that activates the native preview language server and registers all language features._packages/native-preview/src/api/node/protocol.ts— Protocol definitions for IPC communication between Go compiler and Node.js—defines all message types and serialization._packages/native-preview/src/api/options.ts— Configuration and options management for both CLI and LSP; governs all compiler behavior flags..github/copilot-instructions.md— Coding guidelines and architectural patterns specific to this ported codebase; required reading for consistent contributions.
🛠️How to make changes
Add a new Language Feature to VS Code Extension
- Create a new feature file in _extension/src/languageFeatures/ (e.g., newFeature.ts) implementing the VS Code provider interface (
_extension/src/languageFeatures/newFeature.ts) - Register the provider in extension.ts by creating a registration call via context.subscriptions.push() (
_extension/src/extension.ts) - Delegate to the LSP client (this.client) to send protocol messages to the native server (
_extension/src/client.ts)
Add a new Compiler Option or Configuration Flag
- Define the option in _packages/native-preview/src/api/options.ts under CompilerOptions or LSPOptions interface (
_packages/native-preview/src/api/options.ts) - Update protocol.ts to include the new option in the Request/Response message types if it affects IPC (
_packages/native-preview/src/api/node/protocol.ts) - Pass the option through the client API (sync/client.ts or async/client.ts) to the protocol layer (
_packages/native-preview/src/api/sync/client.ts)
Improve IPC Performance or Add a New Protocol Message
- Define the new message type in protocol.ts following the existing RPC pattern (
_packages/native-preview/src/api/node/protocol.ts) - Implement encoding/decoding in encoder.ts to serialize the message using MessagePack (
_packages/native-preview/src/api/node/encoder.ts) - Add the handler in node.ts to route the message to/from the Go subprocess (
_packages/native-preview/src/api/node/node.ts) - Expose the new capability through the sync or async client API (
_packages/native-preview/src/api/sync/client.ts)
🔧Why these technologies
- Go (compiler core) — Rewrite of TypeScript compiler for performance; Go's concurrency, memory management, and compile speed far exceed JavaScript/Node.js alternatives.
- MessagePack IPC protocol — Binary serialization minimizes overhead in subprocess communication; more efficient than JSON for large type information payloads.
- VS Code Language Server Protocol (LSP) — Standard editor integration layer; decouples compiler from editor UI and enables multi-editor support without reimplementation.
- Node.js adapter — Bridges CLI and LSP consumers to Go compiler; maintains backward compatibility with JavaScript ecosystem and npm tooling.
⚖️Trade-offs already made
-
Single-process Go compiler spawned per workspace
- Why: Simplifies lifecycle management and avoids process pool complexity; ensures consistent compiler state.
- Consequence: Compiler restarts on configuration changes; some operations (e.g., large projects) block the event loop until IPC response arrives in sync client.
-
Sync client API for CLI (tsgo), async for LSP
- Why: CLI requires blocking semantics (tsc compatibility); LSP requires async to remain responsive to editor events.
- Consequence: Two separate client implementations with duplicated logic; CLI throughput limited by blocking I/O.
-
In-memory sourceFileCache without persistence
- Why: Fast hit-rates for incremental compilations within a session; avoids serialization overhead.
- Consequence: Cache is lost on process restart; no cross-session optimization; memory footprint grows with project size.
-
Full protocol code generation via .generated files
- Why: Ensures encoder/protocol stay in sync; reduces manual IPC bugs.
- Consequence: Build step required to update IPC layer; adds complexity to contributor workflow.
🚫Non-goals (don't propose these)
- Does not implement full LSP (only core language features: hover, highlights, diagnostics, source definition).
- Does not support all TypeScript compiler options yet (README notes partial coverage).
- Does not include a language-server binary distribution (currently Node.js wrapper only).
- Does not handle authentication or multi-user scenarios.
- Not production-ready for end users—marked as 'Native Preview' and under active development.
🪤Traps & gotchas
Major: The repo will eventually close and merge into microsoft/TypeScript—do not expect long-term stability or a separate issue tracker. Build tooling: The exact Go module structure and build entry point are not fully visible; the Herebyfile.mjs is likely the source of truth (not shown in full). Feature parity trap: Watch mode is prototype-only and will panic or silently fail; JSDoc and declaration emit for JS are incomplete despite being marked 'in progress'—do not assume feature completeness from status badges. Extension quirk: The extension requires js/ts.experimental.useTsgo and may require restarting VS Code; caching or stale processes can hide bugs.
🏗️Architecture
💡Concepts to learn
- Language Server Protocol (LSP) — The native Go compiler is wrapped as an LSP server to communicate with VS Code; understanding LSP is essential to debug editor integration issues and extend language service features
- Fourslash Testing Framework — The codebase uses TypeScript's fourslash test format (embedded markers in source files); you'll need to write and debug tests using this system for parser, type checker, and IDE features
- Module Resolution (CommonJS, ESM, Node, Bundler modes) — The compiler implements TypeScript's module resolution algorithm; bugs in import/export handling stem from divergence in these modes, which are explicitly incomplete per the README
- Type Narrowing & Type Guards — TypeScript's type inference engine relies on control-flow analysis and guard patterns; the Go port must replicate this exactly to claim feature parity
- Declaration Emit (
.d.tsgeneration) — Marked 'in progress' for JS files; this is a complex feature that requires synthesizing type information into.d.tsoutput—a major missing piece - Go generics (Go 1.18+) — The Go implementation likely uses generics for AST node handling and type constraints; understanding Go's generic syntax is crucial for modifying the core compiler
- Incremental Compilation & Dependency Graphs — Build mode and incremental build are marked 'done'; the port likely maintains a module dependency graph to skip rechecking unchanged files, a pattern you'll encounter when optimizing watch mode
🔗Related repos
microsoft/TypeScript— The original TypeScript compiler in JavaScript; this repo is a native port that will eventually be merged back into itgolang/tools— Contains gopls, the Go language server—architectural inspiration and reference for LSP implementation patterns used in this portevanw/esbuild— Alternative native compiler for JavaScript/TypeScript written in Go; demonstrates feasibility of the native port approach and performance benchmarksswc-project/swc— Rust-based JavaScript/TypeScript compiler with similar goals of native-speed tooling; relevant competitor and design reference
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Implement VS Code extension language feature tests for documentHighlight and hover
The _extension/src/languageFeatures/ directory contains implementations for documentHighlight.ts and hover.ts, but there are no corresponding test files in the repo structure. These are critical editor features that need automated test coverage to catch regressions as the native Go port evolves. This is especially important given the 'preview' status and the need to maintain parity with the original TypeScript implementation.
- [ ] Create _extension/src/languageFeatures/tests/documentHighlight.test.ts with test cases for multi-document highlight provider scenarios
- [ ] Create _extension/src/languageFeatures/tests/hover.test.ts covering basic hover, hover with editorHoverVerbosityLevel proposal API, and null cases
- [ ] Add test fixtures in _extension/src/languageFeatures/tests/fixtures/ with sample TypeScript/JavaScript files
- [ ] Update CI workflow in .github/workflows/ci.yml to run extension tests as part of the build pipeline
Add comprehensive configuration validation and documentation for typescript.native-preview settings
The package.json shows several experimental configuration properties (customConfigFileName, trace.server, ppr...) but the description for 'ppr' is truncated. The CONTRIBUTING.md and README.md don't document what these settings do or how to use them. This creates friction for extension users and contributors trying to configure the native preview.
- [ ] Complete the truncated 'ppr' configuration property definition in _extension/package.json with proper description and enum values
- [ ] Create _extension/CONFIGURATION.md documenting all typescript.native-preview.* settings with examples and use cases
- [ ] Add validation logic in _extension/src/configurationMiddleware.ts to catch invalid configuration values and provide helpful error messages
- [ ] Update CONTRIBUTING.md with a section 'Extension Configuration Guide' linking to the new documentation
Create integration tests for the Go language server startup and session management
The _extension/src/session.ts and _extension/src/client.ts files handle critical server initialization and communication, but there's no visible test coverage for server lifecycle management (.github/actions/setup-go suggests Go tooling is available). Given this is a staging repo for a native port, ensuring the Go server reliably starts, connects, and recovers from errors is essential.
- [ ] Create a new test directory _extension/src/tests/session.test.ts covering session initialization, reconnection, and error recovery scenarios
- [ ] Create _extension/src/tests/client.test.ts to test Go server communication (LSP protocol compliance, timeout handling)
- [ ] Add mock Go server helper in _extension/src/tests/fixtures/mockGoServer.ts for testing without a real binary
- [ ] Add integration test job to .github/workflows/ci.yml that spins up the extension and verifies the language server responds to basic requests
🌿Good first issues
- Add exhaustive fourslash tests for the
declaration emitfeature in JS files (marked 'in progress' in README); the test infrastructure exists in.github/skills/compiler-and-fourslash-tests/but coverage is likely incomplete. - Audit and document all intentional changes from TypeScript 6.0 beyond what's in
CHANGES.md; cross-reference the Go implementation against the original TS compiler to surface undocumented behavioral divergence. - Implement incremental rechecking in watch mode (currently prototype); the watch skeleton exists but reuses the full type-check pipeline—optimize to only recheck affected modules, following the incremental build logic already done for build mode.
⭐Top contributors
Click to expand
Top contributors
- @Copilot — 18 commits
- @ahejlsberg — 15 commits
- @jakebailey — 13 commits
- @andrewbranch — 10 commits
- @Andarist — 9 commits
📝Recent commits
Click to expand
Recent commits
e1f8f97— Fix package index fallback edge case, accept self-name resolution errors under ambiguous project root (#3776) (andrewbranch)5eb880f— Move jsDeclarationsModuleReferenceHasEmit baseline from submoduleTriaged to submoduleAccepted (#3764) (Copilot)e070bc6— Fix isInitialized not restored after tryRestart (#3643) (Copilot)c872613— Only transform expando assignments that wont be represented elsewhere in the emit already (#3741) (weswigham)5c67e17— Add PR template for Copilot (#3773) (RyanCavanaugh)bd26028— Move jsDeclarationsExportFormsErr baseline from submoduleTriaged to submoduleAccepted (#3763) (Copilot)e7fe844— Add missing type argument count sanity check to handle nodes from js … (#3745) (weswigham)88f5792— Only include visible expando functions in declaration emit output (#3716) (weswigham)30ee831— Fix crash on completing default import identifiers whenfromis on following line (#3767) (DanielRosenwasser)b6de67f— Defer global ambient module merging ininitializeChecker(#3770) (ahejlsberg)
🔒Security observations
The codebase demonstrates reasonable security practices with proper vulnerability reporting procedures (SECURITY.md) and workspace trust controls. The main concerns are around experimental API usage, automatic extension activation patterns, and lack of visible dependency lock file management. No critical vulnerabilities, hardcoded secrets, or injection risks were identified in the provided code structure. The project is a TypeScript native port under active development, which is typical for staging repositories. Recommended focus areas: validate experimental API stability, document activation behavior, and ensure lock file integrity in CI/CD pipelines.
- Medium · Untrusted Workspaces Not Supported —
_packages/native-preview/package.json - capabilities.untrustedWorkspaces. The VS Code extension declares 'untrustedWorkspaces.supported: false' in package.json, meaning it cannot run in untrusted workspace folders. This is a security measure, but users may be prompted to trust the workspace to use the extension, which could reduce security awareness. Fix: Consider implementing proper workspace trust handling or document why untrusted workspaces are not supported. Evaluate if the extension can safely operate in untrusted contexts. - Medium · Broad Language Activation Events —
_packages/native-preview/package.json - activationEvents. The extension activates on all JavaScript and TypeScript file types (onLanguage events for javascript, javascriptreact, typescript, typescriptreact). This means the native TypeScript server will automatically start for any JS/TS file without explicit user control. Fix: Consider adding user confirmation or configuration to control automatic activation. Document the resource implications of automatic activation. - Low · Experimental Features Without Stability Guarantee —
_packages/native-preview/package.json - enabledApiProposals and contributes.configuration. The package.json includes experimental API proposals (editorHoverVerbosityLevel, multiDocumentHighlightProvider) and configuration properties tagged as 'experimental'. These may not be stable and could change in future VS Code versions. Fix: Maintain clear documentation about which features are experimental. Plan migration strategy for when proposals become stable or are deprecated. - Low · Missing Dependency Lock File Integrity Check —
Root directory - missing lock file visibility. While package.json is provided, there is no visible evidence of package-lock.json or yarn.lock in the file structure shown. This could allow dependency tampering or unexpected updates. Fix: Ensure package-lock.json (or equivalent) is committed and reviewed. Use npm ci instead of npm install in CI/CD pipelines to enforce lock file versions. - Low · Development Container Configuration Present —
.devcontainer/devcontainer.json. A devcontainer.json exists which defines the development environment. While useful for consistency, it should be reviewed for secure base images and no hardcoded secrets. Fix: Review the devcontainer configuration for: official base images with no known CVEs, no hardcoded credentials, and principle of least privilege for container permissions.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.