johnsoncodehk/typescript-native-bridgePublic

A typescript-shaped drop-in backed by typescript-go (tsgo) over an in-process cgo NAPI/FFI bridge — no IPC.

AI summary: A drop-in TypeScript replacement that runs type-checking in-process on Go via an NAPI/FFI bridge.

Stars
300
+3 today
Forks
9
Watchers
3
Open issues
2
Open PRs
0
Contributors
~4
Commits
485
Branches
4

JavaScriptApache-2.0Created Jun 27, 2026Last push 6d agoLatest release v6.0.3-bridge.17.tsgo.7.0.2+3 stars this week+16 this month

Quick answers

What is typescript-native-bridge?
A drop-in TypeScript replacement that runs type-checking in-process on Go via an NAPI/FFI bridge.
What does typescript-native-bridge do?
TypeScript Native Bridge (TNB) provides a high-performance alternative to standard TypeScript type-checking by executing the logic on Microsoft's Go TypeScript compiler (tsgo) instead of JavaScript. It acts as a drop-in replacement for the `typescript` npm package, operating over an in-process cgo NAPI/FFI bridge without relying on inter-process communication (IPC). This architecture allows tools like `tsc`, `vue-tsc`, ESLint, and standard editor LSPs to function exactly as before, but with significantly improved execution speeds. It fundamentally shifts the computational burden of type-checking to a faster, natively compiled backend while maintaining full ecosystem compatibility.
Who is typescript-native-bridge for?
This tool is designed for advanced TypeScript developers and platform engineers managing large codebases who need to optimize type-checking performance. Users must be comfortable modifying their package dependencies and build configurations to utilize a drop-in compiler replacement.
How do I get started with typescript-native-bridge?
Install via npm: npm install typescript-native-bridge
How popular is typescript-native-bridge on GitHub?
johnsoncodehk/typescript-native-bridge has 300 stars and 9 forks on GitHub, and gained 3 stars in the last 7 days.
What license does typescript-native-bridge use?
johnsoncodehk/typescript-native-bridge is released under the Apache-2.0 license.

Star history

since Jul 29, 2026
0100200300Jul 2026Aug 2026Sep 2026Oct 2026
300 stars as of Oct 2, 2026. Measured daily since Jul 29, 2026; GitHub no longer exposes earlier star timestamps.

Contribution activity

commits per day, last 52 weeks
SepOctNovDecJanFebMarAprMayJunJulAugSepMonWedFri2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 0 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 0 commits2026-04-04: 0 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 0 commits2026-04-13: 0 commits2026-04-14: 0 commits2026-04-15: 0 commits2026-04-16: 0 commits2026-04-17: 0 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 0 commits2026-04-21: 0 commits2026-04-22: 0 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 0 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 1 commit2026-06-28: 0 commits2026-06-29: 18 commits2026-06-30: 16 commits2026-07-01: 10 commits2026-07-02: 8 commits2026-07-03: 16 commits2026-07-04: 11 commits2026-07-05: 9 commits2026-07-06: 6 commits2026-07-07: 3 commits2026-07-08: 4 commits2026-07-09: 8 commits2026-07-10: 4 commits2026-07-11: 4 commits2026-07-12: 9 commits2026-07-13: 12 commits2026-07-14: 8 commits2026-07-15: 5 commits2026-07-16: 8 commits2026-07-17: 24 commits2026-07-18: 22 commits2026-07-19: 10 commits2026-07-20: 25 commits2026-07-21: 3 commits2026-07-22: 11 commits2026-07-23: 26 commits2026-07-24: 34 commits2026-07-25: 6 commits2026-07-26: 8 commits2026-07-27: 39 commits2026-07-28: 0 commits2026-07-29: 1 commit2026-07-30: 0 commits2026-07-31: 14 commits2026-08-01: 18 commits2026-08-02: 11 commits2026-08-03: 10 commits2026-08-04: 7 commits2026-08-05: 13 commits2026-08-06: 6 commits2026-08-07: 0 commits2026-08-08: 0 commits2026-08-09: 0 commits2026-08-10: 0 commits2026-08-11: 0 commits2026-08-12: 0 commits2026-08-13: 1 commit2026-08-14: 2 commits2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 2 commits2026-08-23: 5 commits2026-08-24: 7 commits2026-08-25: 6 commits2026-08-26: 0 commits2026-08-27: 0 commits2026-08-28: 0 commits2026-08-29: 0 commits2026-08-30: 0 commits2026-08-31: 0 commits2026-09-01: 0 commits2026-09-02: 0 commits2026-09-03: 7 commits2026-09-04: 0 commits2026-09-05: 0 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 0 commits2026-09-09: 0 commits2026-09-10: 0 commits2026-09-11: 0 commits2026-09-12: 2 commits2026-09-13: 3 commits2026-09-14: 0 commits2026-09-15: 0 commits2026-09-16: 0 commits2026-09-17: 0 commits2026-09-18: 0 commits2026-09-19: 0 commits2026-09-20: 0 commits2026-09-21: 0 commits2026-09-22: 0 commits2026-09-23: 0 commits2026-09-24: 0 commits2026-09-25: 0 commits2026-09-26: 0 commits
483 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Permissive license

    Apache-2.0

  • Continuous integration

    Automated checks passing

What typescript-native-bridge does

TypeScript Native Bridge (TNB) provides a high-performance alternative to standard TypeScript type-checking by executing the logic on Microsoft's Go TypeScript compiler (tsgo) instead of JavaScript. It acts as a drop-in replacement for the `typescript` npm package, operating over an in-process cgo NAPI/FFI bridge without relying on inter-process communication (IPC). This architecture allows tools like `tsc`, `vue-tsc`, ESLint, and standard editor LSPs to function exactly as before, but with significantly improved execution speeds. It fundamentally shifts the computational burden of type-checking to a faster, natively compiled backend while maintaining full ecosystem compatibility.

This tool is designed for advanced TypeScript developers and platform engineers managing large codebases who need to optimize type-checking performance. Users must be comfortable modifying their package dependencies and build configurations to utilize a drop-in compiler replacement.

  • Go-backed type checking: Utilizes Microsoft's Go TypeScript compiler (tsgo) to perform type validation, bypassing the Node.js V8 engine.
  • In-process bridge: Connects JavaScript tooling to the Go compiler via a cgo NAPI/FFI bridge, eliminating slow IPC overhead.
  • Drop-in ecosystem compatibility: Seamlessly replaces the standard `typescript` package, requiring no new CLIs, LSPs, or structural changes to existing projects.
  • Broad tool support: Works natively with popular ecosystem tools including `vue-tsc`, `svelte-check`, `astro-check`, and ESLint.
  • Performance optimization: Significantly reduces the time required for full project type-checking and editor feedback loops.

Where teams use it

Large-scale monorepo type-checking

Enterprise teams swap in TNB to drastically reduce the time it takes to run `tsc` across massive codebases during CI pipelines.

Framework-specific tooling acceleration

Developers using Vue, Svelte, or Astro integrate the bridge to speed up their specialized type-checking commands like `vue-tsc`.

Editor performance enhancement

Engineers replace their workspace TypeScript version with TNB to achieve faster intellisense and error reporting within their IDEs.

Linting optimization

Teams using TypeScript-aware ESLint rules rely on the Go backend to accelerate their linting step prior to committing code.

Getting started: Install via npm: npm install typescript-native-bridge

README

master branch

typescript-native-bridge (TNB)

Published on npm as typescript-native-bridge.

A drop-in typescript replacement that type-checks on Go. Swap the typescript package for this fork and keep using tsc, vue-tsc, svelte-check, astro-check, glint, ESLint, and your editor exactly as before — the checker runs on tsgo (Microsoft's Go TypeScript compiler) in-process instead of JavaScript. No new CLI, no new LSP, no per-tool config, no code changes.


Why not just use TypeScript 7 (tsgo)?

typescript@7 is Microsoft's Go-native rewrite — but it doesn't drop into the tools you actually use:

  • vue-tsc / astro-check / svelte-check / glint are built on the classic typescript programmatic API (createProgram, Volar hooks, custom hosts). v7's programmatic surface is the new tsgo API — not a drop-in replacement for the classic one, so those tools can't just move to it.
  • ESLint (typescript-eslint) imports the classic typescript API and calls getTypeChecker() — same API mismatch.
  • Editors run tsserver + Language Service Plugins (@vue/typescript-plugin for .vue) — tsgo's LSP doesn't support that plugin model.

TNB keeps the classic package surface and puts the v7 engine (tsgo 7.x) behind it in-process — so one typescript override accelerates all of them at once.


Install

pnpm (monorepos)

# pnpm-workspace.yaml
overrides:
  typescript: npm:typescript-native-bridge@<version>
pnpm install
pnpm exec vue-tsc -b --noEmit    # or your project's typecheck script

If packages depend on typescript via catalog:, update the catalog entry too, or those packages still resolve stock TypeScript:

catalog:
  typescript: npm:typescript-native-bridge@<version>
overrides:
  typescript: npm:typescript-native-bridge@<version>

npm

// package.json
{
  "devDependencies": {
    "typescript": "npm:typescript-native-bridge@<version>"
  },
  "overrides": {
    "typescript": "$typescript"
  }
}

Use the alias and the $typescript override reference as shown — putting npm:typescript-native-bridge@… directly inside overrides is rejected or mis-resolved by some npm versions (issue #8). <version> is an exact version (e.g. 6.0.3-bridge.6.tsgo.7.0.2 — pin exactly; caret ranges don't match prerelease versions) or the latest dist-tag.

yarn

// package.json
{
  "resolutions": {
    "typescript": "npm:typescript-native-bridge@<version>"
  }
}

Local path (pinning a git checkout)

# pnpm-workspace.yaml
overrides:
  typescript: link:../typescript-native-bridge

The checkout must be built first (requires Go — npm run setup in the TNB repo).

After any override change: reinstall. The override applies repo-wide — vue-tsc, @typescript-eslint/parser, and every other transitive typescript consumer picks up the fork.


Confirm it's working

On the first type-check in a process, TNB prints one dimmed line to stderr:

▎ TNB ACTIVE — `typescript` is the tsgo-backed fork

No banner = stock typescript is still loaded. See Troubleshooting.

node -e "console.log(require.resolve('typescript'))"
# should point at typescript-native-bridge, not node_modules/typescript@6.x

Verified compatible tools

Verified means: the tool runs on the fork and its behavior matches tsgo's on the stated workload (no crash, no silent under-reporting, no false positives beyond the differences from tsgo).

Tool Status Verified on
tsc ✅ compiler test corpus
vue-tsc ✅ elk.zone monorepo (~2,000 files): emitted-error parity with stock, ~3× faster
astro-check ✅ fixture project: output identical to stock
svelte-check ✅ fixture project: output identical to stock (incl. svelteHTML ambient shims)
glint ✅ fixture project: same error set as stock (transformed .gts virtual files)
mdx-tsc ✅ fixture project: diagnostic output identical to stock (Volar runTsc, errors mapped to MDX source spans)
ESLint + typescript-eslint (type-aware rules) ✅ 1,000-file type-aware corpus: lint output byte-identical to stock
tsserver + @vue/typescript-plugin ✅ volar language-tools test suite: 205/209 pass (4 skipped)
tsslint ✅ runs as the volar repo's own linter

Continuous verification: a CI gate (every push/PR and nightly) replays the language-service probe corpus (quickinfo / definition / references / diagnostics, ~19k units) against the same stock build — no new divergences allowed. If your tool isn't listed, try it and file an issue; the fork covers any tool that drives the standard typescript Compiler API.

Framework specifics

  • .vue, .svelte, .astro, .mdx, .gts etc. via the standard extraFileExtensions contract — no hard-coded per-framework special case.
  • Host-injected virtual content (Volar virtual TS, glint's transformed modules, svelte's ambient shims) reaches the Go checker.
  • allowArbitraryExtensions is inferred true when host extra extensions are present and tsconfig leaves it unset; explicit false opts out.
  • Not supported: custom resolveModuleNames / resolveModuleNameLiterals that remap an import to a different physical file (the bridge is synchronous JS→Go; tsgo cannot call back into JS resolvers).

Performance

Measured on this repo's benchmarks (Apple Silicon; your repo will differ — measure):

Workload Stock typescript TNB
vue-tsc -b full check (elk.zone, ~2,000 files) 9.7s 3.2s ~3×
type-aware ESLint, single-run (1,000 plain-TS files, one program) 2.3s 2.4s +1.5%
same, 3,000 files 6.9s 6.8s ~parity
JS heap peak (1,000-file ESLint fixture) 769MB 631MB −18%
peak RSS, whole-process (vue-tsc -b; TNB's includes the in-process Go checker) 1.8GB 3.3GB ~1.9× — structural

The rule is simple: wherever the time is in the checker, TNB is faster. The question for any workload is how much of its time that phase is — and how much of it pays the JS↔Go boundary instead.

vue-tsc -b (checker-dominated — the big win): the whole-program semantic pass drops from ~5.5s (JS checker) to ~1.5s (Go checker), and most of stock's ~2.6s full-program parse+bind never happens — TNB's thin program materializes files lazily, on demand. The rest is Volar codegen and JS-side work both sides pay. The Go checker's in-process program state is also why TNB's whole-process RSS runs higher than stock's on this workload — JS heap stays lower; RSS is the honest whole-process figure.

Editor / LS path (Volar + tsserver): the V8-arena transport (fixed-layout records written straight into V8 memory, DataView reads, interned strings) keeps per-keystroke work near the transport floor. Measured on a 5,537-request roam over the volar corpus (one long-lived session): ~1.0 bridge RPC per request; p50 quickinfo 0.16ms, completionInfo 0.23ms, references 1.5ms (p95 7.4 / 9.0 / 48ms — means are tail-dominated). Per-request byte figures in older revisions of this section described the bridge-internal JS↔Go channel, not the editor-facing tsserver wire.

The carve-out — single-run type-aware ESLint is the workload with the least to gain. Its time is in parsing, AST conversion and rule execution (work both sides pay), and its type-aware queries arrive as tens of thousands of tiny calls (~44K checker RPCs per 1,000 files after the bridge's per-generation memoizing) that measure the JS↔Go boundary, not the engine. TNB lands within ~2% of stock at both sizes — parity, not a win; peak JS heap stays at or below stock. The memory wins live on the long-session editor path (see release notes).


Editor / tsserver (VS Code, Cursor)

CLI typecheck picks up TNB automatically. The editor does not — VS Code ships its own TypeScript and only uses yours when you opt in.

1. Workspace settings (commit .vscode/settings.json for the team):

{
  "js/ts.tsdk.path": "node_modules/typescript/lib",
  "js/ts.tsdk.promptToUseWorkspaceVersion": true
}

Use a path relative to the workspace folder that contains node_modules.

2. Switch to the workspace version (once per machine):

Command Palette → TypeScript: Select TypeScript Version → Use Workspace Version.

3. Verify: the version picker shows a path under node_modules/typescript/lib; the Output → TypeScript channel may show TNB ACTIVE on first project load. Vue/Nuxt users: keep @vue/typescript-plugin in tsconfig compilerOptions.plugins as today — it runs as a tsserver LS Plugin on this fork.

CLI Editor
Override needed Yes Yes (same node_modules/typescript)
Extra config No js/ts.tsdk.path + Use Workspace Version

Behavior and differences from tsgo

The checker's behavior is tsgo 7.0.2's (Microsoft's Go TypeScript), not stock TypeScript 6.0.3's — migrating from stock means inheriting tsgo's diagnostics, bundled libs, and display output as-is.

TNB's own changes to tsgo behavior — the complete list, enforced by CI:

Change Why Upstream Removal
getTypeFromTypeNodeWorker resolves type-position entity names (identifier / qualified name / property access) Silent wrong result on the headline path: hover on P in [P, (typeof OBJ)[P][number]] read any instead of the type parameter (issue #30) repro branch repro/type-position-entity-reads-any (issue pending) When the upstream fix lands
tsgo-symbolflags-typealias-display: typeParametersToTypeParameterDeclarations checks `Class Interface TypeAlias(stock'sSymbolFlags.TypeAlias) instead of Class Interface
tsgo-immaliased-nil — bridge-only guard (no tsgo behavior change): getImmediateAliasedSymbol returns nil instead of panicking for declaration-less synthetic aliases; only the bridge's exposed API can hit the branch — tsgo's own callers already nil-check the result A Go panic on the bridge's NAPI boundary is process-fatal where stock's failure is a catchable JS throw — —
tsgo-instsymbol-active-guard — bridge-only guard (no tsgo behavior change): getTypeOfInstantiatedSymbol/getWriteTypeOfInstantiatedSymbol dispatch by flags when cross-checker reuse yields a nil target or a cyclic instantiation chain; the guards never fire on stock-shaped data Per-checker valueSymbolLinks go empty/cyclic only when the bridge reuses a SymbolHandle across checkers — —
tsgo-ctx-initializer-nil-guard — bridge-only guard (no tsgo behavior change): getContextualType returns nil for a parentless node instead of nil-dereferencing; parsed trees always parent non-root nodes, so only the bridge's GetContextualType RPC can supply one The bridge runs stock-derived callers that can pass synthetic/parentless nodes — —
tsgo-extra-file-extensions — extraFileExtensions resolution surface (stock parity): host-registered extensions (e.g. .vue) are threaded through program loading, triple-slash/type-reference/module resolution, string-completion extension search, parse script-kind inference, and the checked-file completion path; allowArbitraryExtensions is inferred when unset; typeRoot resolutions carry stock's PackageId Volar/svelte-check-style language plugins register extraFileExtensions; stock resolves the registered host file and completes inside it, tsgo previously ignored the option (nil everywhere) and misclassified/resolved these files upstream issue pending When upstream implements the extraFileExtensions surface
tsgo-checker-pool-strides — whole-program diagnostics assign files to checkers by index stride (i % groups) with checker releases deferred past RunAndWait, instead of goroutine-scheduled queue pickup Checker-local lazy state (merged-global heritage resolution, report dedup) made per-file blame appear/disappear across identical runs (issue #42), and small programs riding a single dedicated checker deterministically dropped merged-global TS2430 blame sites that both stock tsc and the strided pool report (issues #42/#51) upstream issue pending When tsgo's whole-program pass is run-stable by construction
tsgo-autoimport-kind-alias — auto-import createExport presents the export-map entry's ScriptElementKind as alias (the entry's own kind) instead of the target symbol's kind Auto-import entries showed the target's kind (e.g. class) where stock shows alias; kind drives the completion icon editors render upstream issue pending When upstream fixes the export-map entry kind
tsgo-autoimport-inprogram-gate — auto-import search only surfaces a package's exports-subpath modules when the package is a package.json-listed dependency or the module is already in the program Without the gate, a dependency's exports-subpath modules (never in the program, never provider-covered) leaked in as auto-import candidates stock never offers upstream issue pending When upstream implements stock's coverage split
tsgo-typeat-nil-parent-guard — bridge-only guard (no tsgo behavior change): GetTypeOfSymbolAtLocation nil-checks location.Parent before JSX/set-accessor classification; parsed trees always parent non-root nodes, so only the bridge's GetTypeOfSymbolAtLocation RPC can supply a parentless location A Go nil-dereference on the bridge's NAPI boundary is process-fatal where stock's failure is a catchable JS throw — —
tsgo-osvfs-executable-fallback — isFileSystemCaseSensitive silently falls back (case-insensitive on darwin/windows, case-sensitive elsewhere) when os.Executable fails, instead of panicking Forked Node workers (vitest pool=forks) may not resolve argv0 on macOS, and the panic is process-fatal on the bridge where stock's sys.ts is equally best-effort about __filename upstream issue pending When upstream lands a non-panicking fallback
tsgo-autoimport-markbuckets-dirty — markBucketsDirty keeps a bucket in the markFilesDirty worklist until it actually goes multiple-files-dirty (pristine ejected it after the first mark, before multipleFilesDirty was set, so a second same-batch file's dirty mark was eaten) When two project files change in one update batch, the second file's invalidation was lost on ~50% of runs (map iteration order), leaving its exports stale in auto-import completions (volar #5847); pinned by TestMarkBucketsDirtyTwoFileBatchBothLand volar #5847; upstream issue pending When upstream fixes the worklist ejection
tsgo-declaredtype-nil-symbol — bridge-only guard (no tsgo behavior change): tryGetDeclaredTypeOfSymbol returns nil for a nil symbol instead of nil-dereferencing; a type-only ImportClause is an IsTypeDeclaration node the binder never gives a symbol, and only the bridge's GetTypeAtLocation RPC supplies such nodes — tsgo's own LSP routes hover types through shouldGetType's kind allowlist, which excludes ImportClause (issue #71) A Go panic on the bridge's NAPI boundary is process-fatal where stock's failure is a catchable JS throw — —
tsgo-tuple-base-type-target — bridge-only guard (no tsgo behavior change): getBaseTypes resolves a tuple through its target and getTupleBaseType reads the readonly modifier off the type the caller asked about, so the arity-0 array-literal clone (Tuple in its own objectFlags, *TypeReference data — no tuple data, no readonly field, exactly what stock reads as undefined) answers the mutable never[] while a declared readonly [] keeps readonly never[]; the nil-data arm returns no base types instead of dereferencing nil A Go panic on the bridge's NAPI boundary is process-fatal where stock answers, and the exposed GetBaseTypes RPC accepts any type — tsgo's own callers only pass types they already know to be class or interface (issue #73) microsoft/TypeScript#63869 — fixed by the merged #64080, which guards tuple data at the proto SERIALIZER only and leaves getBaseTypes untouched; the getBaseTypes hole is unfixed upstream at main. The unmerged typescript-go#4803 / #4870 proposed the same target read When tools/check-pristine-attribution.mjs reports UPSTREAM-FIXED for this key — i.e. the pristine clone at the pin no longer panics on the repro test

Anything that looks like a difference from stock 6.0.3 but isn't listed here is tsgo's own behavior, not TNB's. Found an actual TNB-only divergence? File an issue with a minimal repro.


Platform support

The bridge binary ships as per-platform optional dependencies; npm install pulls only the one matching your machine (the main package is pure JS):

Platform Sub-package
macOS Apple Silicon @typescript-native-bridge/darwin-arm64
macOS Intel @typescript-native-bridge/darwin-x64
Linux x64 @typescript-native-bridge/linux-x64
Linux arm64 @typescript-native-bridge/linux-arm64
Linux arm (32-bit) @typescript-native-bridge/linux-arm
Windows x64 @typescript-native-bridge/win32-x64
Windows arm64 @typescript-native-bridge/win32-arm64

Linux packages target glibc 2.35 and are rejected by the release gate if they acquire a newer symbol requirement. (They targeted 2.31 until bridge.17, built on debian:bullseye-slim; Debian retired those packages from the bullseye-security pool in 2026-09 so the image can no longer install its own build dependencies, and the successor floor is Ubuntu 22.04 / jammy.) Alpine/musl is not supported: Go's -buildmode=c-shared runtime crashes at load on musl libc — even a trivial hello-world c-shared library segfaults, on Go 1.22 through 1.26 alike (golang/go#13492, a 10-year-open upstream issue with an active fix in golang/go#75048; tsgo's own CLI works on Alpine only because it ships CGO-free static binaries, and a NAPI bridge cannot be CGO-free). Workaround: run the typecheck/lint step in a glibc-based image (node:24 or node:24-bookworm-slim) and deploy into the Alpine stage of your multi-stage build; apk add gcompat does not help.

On an unsupported platform the loader fails with a clear "unsupported platform or missing optional dependency" error — build from source there (clone with submodules, then npm run setup; requires Go + a C toolchain).


Troubleshooting

No banner appears

Check Action
Override at workspace root Monorepo: pnpm-workspace.yaml, not a leaf package
pnpm 11 Move package.json → pnpm.overrides to pnpm-workspace.yaml → overrides: (pnpm 11 no longer reads the pnpm field — silently ignored)
catalog: pin Update catalog and overrides
Stale install pnpm install again; clear CI cache if needed
Wrong resolution node -e "console.log(require.resolve('typescript'))"

CLI works, editor doesn't (or vice versa)

  • CLI OK, editor not: add the tsdk settings and run TypeScript: Select TypeScript Version → Use Workspace Version. The override alone is not enough for the editor.
  • Editor OK, CLI not: check require.resolve('typescript') — should point at TNB. Reinstall after changing overrides.

Type errors differ from stock

Expected — the checker's behavior is tsgo 7.0.2's, not stock 6.0.3's, so output can differ from stock (see Behavior and differences from tsgo). What is a bug: output that differs from tsgo itself — file an issue with a minimal repro.

Missing native bridge

Error mentioning bridge.dylib / bridge.so / bridge.dll / "unsupported platform" → see Platform support (build from source, or use a link: install built with npm run setup).

Debug a slow run

TSGO_PROFILE=1 prints a [tsgo-profile] RPC/timing summary to stderr on process exit.


Uninstall / rollback

Remove the typescript override, reinstall, confirm:

pnpm install
node -e "console.log(require.resolve('typescript'))"   # stock typescript@6.x again

No source changes required.


FAQ

Do I need to change my code? No.

Do I configure vue-tsc / ESLint / my editor plugin separately? No. They import typescript; one override covers them.

Is this the same as TypeScript 7 / tsgo? Same engine, different package. TNB pins tsgo 7.x as its checker (the version string ends in tsgo.7.0.2), but keeps the classic typescript API and tsserver in front of it. typescript@7 gives you the new tsgo API and its own LSP instead — see Why not just use TypeScript 7?

How much faster is it? See Performance — biggest on vue-tsc-style full-program workloads. Measure on your own repo.


License

Apache-2.0. See LICENSE and NOTICE.

This package is a derivative work of Microsoft TypeScript and microsoft/typescript-go.

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

17 total
  1. v6.0.3-bridge.17.tsgo.7.0.2v6.0.3-bridge.17.tsgo.7.0.2Sep 13, 2026

    **Full Changelog**: https://github.com/johnsoncodehk/typescript-native-bridge/compare/v6.0.3-bridge.16.tsgo.7.0.2...v6.0.3-bridge.17.tsgo.7.0.2

  2. v6.0.3-bridge.16.tsgo.7.0.2v6.0.3-bridge.16.tsgo.7.0.2Sep 3, 2026

    Crash fixes for three tsserver-killing Go panics, plus the gates that close the bug class. ## Fixes - **Go panic on cloned tuple references** (#69, #70) — `Type.ThisType` gated on `objectFlags`, but flags travel with clones while the data shape doesn't: a cloned tuple reference carries `ObjectFlags.Tuple` with `*TypeReference` data, so `AsInterfaceType().thisType` nil-deref'd the process. Gates on the data shape now. - **Go panic on symbol-less type declarations** (#71) — `tryGetDeclaredTypeOfSymbol` nil-deref'd on declarations with no symbol; returns the error type (stock behavior). - **Same-class sweep** — the symbol walker's interface visit and the override-status accessor carried the same shape assumption; both guard on the actual data shape now. ## Gates closing the bug class - `check:go-as-guards` — static: every `Type.As*()` chained deref and unguarded nil-family assignment in the tsgo patches/overlay is guarded or carries a verified inline `asguard:exempt` reason (16 sites, each checked against the constructors). - `triage-checker-fullwalk` — dynamic: the checker-API stock differential walks every corpus node with a 14-field lazy-accessor closure per type (the reads tha

  3. v6.0.3-bridge.15.tsgo.7.0.2v6.0.3-bridge.15.tsgo.7.0.2Aug 24, 2026

    **Full Changelog**: https://github.com/johnsoncodehk/typescript-native-bridge/compare/v6.0.3-bridge.14.tsgo.7.0.2...v6.0.3-bridge.15.tsgo.7.0.2

  4. v6.0.3-bridge.14.tsgo.7.0.2v6.0.3-bridge.14.tsgo.7.0.2Aug 23, 2026

    **Full Changelog**: https://github.com/johnsoncodehk/typescript-native-bridge/compare/v6.0.3-bridge.13.tsgo.7.0.2...v6.0.3-bridge.14.tsgo.7.0.2

  5. v6.0.3-bridge.13.tsgo.7.0.2v6.0.3-bridge.13.tsgo.7.0.2Aug 13, 2026

    ## What's Changed * fix(bridge): preserve `Type` API routing after snapshot refresh by @KazariAI in https://github.com/johnsoncodehk/typescript-native-bridge/pull/59 * fix(bridge): resolve native auto-import completions by @KazariAI in https://github.com/johnsoncodehk/typescript-native-bridge/pull/61 **Full Changelog**: https://github.com/johnsoncodehk/typescript-native-bridge/compare/v6.0.3-bridge.12.tsgo.7.0.2...v6.0.3-bridge.13.tsgo.7.0.2

Code frequency

additions and deletions
+101.8K-101.8KWeek of 2026-06-21: +2,217 linesWeek of 2026-06-21: -0 linesWeek of 2026-06-28: +11,742 linesWeek of 2026-06-28: -4,478 linesWeek of 2026-07-05: +21,194 linesWeek of 2026-07-05: -5,424 linesWeek of 2026-07-12: +71,548 linesWeek of 2026-07-12: -27,137 linesWeek of 2026-07-19: +64,918 linesWeek of 2026-07-19: -70,527 linesWeek of 2026-07-26: +94,121 linesWeek of 2026-07-26: -84,224 linesWeek of 2026-08-02: +101,750 linesWeek of 2026-08-02: -97,153 linesWeek of 2026-08-09: +451 linesWeek of 2026-08-09: -119 linesWeek of 2026-08-16: +309 linesWeek of 2026-08-16: -45 linesWeek of 2026-08-23: +1,396 linesWeek of 2026-08-23: -176 linesWeek of 2026-08-30: +1,599 linesWeek of 2026-08-30: -71 linesWeek of 2026-09-06: +597 linesWeek of 2026-09-06: -6 linesWeek of 2026-09-13: +102 linesWeek of 2026-09-13: -67 linesWeek of 2026-09-20: +0 linesWeek of 2026-09-20: -0 linesJun 21, 2026Sep 20, 2026
+371.9K lines added, -289.4K removed over the last year.

Commits per week

last 52 weeks
1150Week of 2025-09-28: 0 commitsWeek of 2025-10-05: 0 commitsWeek of 2025-10-12: 0 commitsWeek of 2025-10-19: 0 commitsWeek of 2025-10-26: 0 commitsWeek of 2025-11-02: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 0 commitsWeek of 2026-02-08: 0 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 0 commitsWeek of 2026-03-01: 0 commitsWeek of 2026-03-08: 0 commitsWeek of 2026-03-15: 0 commitsWeek of 2026-03-22: 0 commitsWeek of 2026-03-29: 0 commitsWeek of 2026-04-05: 0 commitsWeek of 2026-04-12: 0 commitsWeek of 2026-04-19: 0 commitsWeek of 2026-04-26: 0 commitsWeek of 2026-05-03: 0 commitsWeek of 2026-05-10: 0 commitsWeek of 2026-05-17: 0 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 0 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 0 commitsWeek of 2026-06-21: 1 commitsWeek of 2026-06-28: 79 commitsWeek of 2026-07-05: 38 commitsWeek of 2026-07-12: 88 commitsWeek of 2026-07-19: 115 commitsWeek of 2026-07-26: 80 commitsWeek of 2026-08-02: 47 commitsWeek of 2026-08-09: 3 commitsWeek of 2026-08-16: 2 commitsWeek of 2026-08-23: 18 commitsWeek of 2026-08-30: 7 commitsWeek of 2026-09-06: 2 commitsWeek of 2026-09-13: 3 commitsWeek of 2026-09-20: 0 commitsSep 28, 2025Sep 20, 2026
483 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 1 commitsSun 1:00 — 5 commitsSun 2:00 — 0 commitsSun 3:00 — 2 commitsSun 4:00 — 2 commitsSun 5:00 — 1 commitsSun 6:00 — 2 commitsSun 7:00 — 0 commitsSun 8:00 — 0 commitsSun 9:00 — 0 commitsSun 10:00 — 1 commitsSun 11:00 — 0 commitsSun 12:00 — 1 commitsSun 13:00 — 1 commitsSun 14:00 — 3 commitsSun 15:00 — 1 commitsSun 16:00 — 4 commitsSun 17:00 — 1 commitsSun 18:00 — 0 commitsSun 19:00 — 8 commitsSun 20:00 — 0 commitsSun 21:00 — 6 commitsSun 22:00 — 9 commitsSun 23:00 — 7 commitsMon 0:00 — 4 commitsMon 1:00 — 4 commitsMon 2:00 — 6 commitsMon 3:00 — 4 commitsMon 4:00 — 13 commitsMon 5:00 — 7 commitsMon 6:00 — 15 commitsMon 7:00 — 4 commitsMon 8:00 — 8 commitsMon 9:00 — 8 commitsMon 10:00 — 6 commitsMon 11:00 — 8 commitsMon 12:00 — 6 commitsMon 13:00 — 3 commitsMon 14:00 — 3 commitsMon 15:00 — 3 commitsMon 16:00 — 2 commitsMon 17:00 — 2 commitsMon 18:00 — 1 commitsMon 19:00 — 1 commitsMon 20:00 — 4 commitsMon 21:00 — 1 commitsMon 22:00 — 1 commitsMon 23:00 — 3 commitsTue 0:00 — 0 commitsTue 1:00 — 2 commitsTue 2:00 — 3 commitsTue 3:00 — 2 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 0 commitsTue 7:00 — 0 commitsTue 8:00 — 3 commitsTue 9:00 — 3 commitsTue 10:00 — 2 commitsTue 11:00 — 2 commitsTue 12:00 — 3 commitsTue 13:00 — 5 commitsTue 14:00 — 2 commitsTue 15:00 — 1 commitsTue 16:00 — 1 commitsTue 17:00 — 1 commitsTue 18:00 — 6 commitsTue 19:00 — 0 commitsTue 20:00 — 4 commitsTue 21:00 — 3 commitsTue 22:00 — 0 commitsTue 23:00 — 0 commitsWed 0:00 — 0 commitsWed 1:00 — 2 commitsWed 2:00 — 2 commitsWed 3:00 — 3 commitsWed 4:00 — 1 commitsWed 5:00 — 1 commitsWed 6:00 — 2 commitsWed 7:00 — 4 commitsWed 8:00 — 1 commitsWed 9:00 — 1 commitsWed 10:00 — 1 commitsWed 11:00 — 0 commitsWed 12:00 — 2 commitsWed 13:00 — 0 commitsWed 14:00 — 2 commitsWed 15:00 — 6 commitsWed 16:00 — 1 commitsWed 17:00 — 2 commitsWed 18:00 — 1 commitsWed 19:00 — 3 commitsWed 20:00 — 3 commitsWed 21:00 — 2 commitsWed 22:00 — 0 commitsWed 23:00 — 4 commitsThu 0:00 — 2 commitsThu 1:00 — 2 commitsThu 2:00 — 1 commitsThu 3:00 — 0 commitsThu 4:00 — 0 commitsThu 5:00 — 0 commitsThu 6:00 — 1 commitsThu 7:00 — 2 commitsThu 8:00 — 7 commitsThu 9:00 — 2 commitsThu 10:00 — 2 commitsThu 11:00 — 1 commitsThu 12:00 — 2 commitsThu 13:00 — 5 commitsThu 14:00 — 7 commitsThu 15:00 — 5 commitsThu 16:00 — 3 commitsThu 17:00 — 2 commitsThu 18:00 — 3 commitsThu 19:00 — 3 commitsThu 20:00 — 4 commitsThu 21:00 — 2 commitsThu 22:00 — 3 commitsThu 23:00 — 5 commitsFri 0:00 — 2 commitsFri 1:00 — 2 commitsFri 2:00 — 2 commitsFri 3:00 — 2 commitsFri 4:00 — 4 commitsFri 5:00 — 3 commitsFri 6:00 — 1 commitsFri 7:00 — 2 commitsFri 8:00 — 9 commitsFri 9:00 — 14 commitsFri 10:00 — 4 commitsFri 11:00 — 3 commitsFri 12:00 — 1 commitsFri 13:00 — 6 commitsFri 14:00 — 3 commitsFri 15:00 — 1 commitsFri 16:00 — 1 commitsFri 17:00 — 1 commitsFri 18:00 — 12 commitsFri 19:00 — 8 commitsFri 20:00 — 8 commitsFri 21:00 — 0 commitsFri 22:00 — 0 commitsFri 23:00 — 5 commitsSat 0:00 — 0 commitsSat 1:00 — 0 commitsSat 2:00 — 2 commitsSat 3:00 — 1 commitsSat 4:00 — 2 commitsSat 5:00 — 5 commitsSat 6:00 — 5 commitsSat 7:00 — 4 commitsSat 8:00 — 8 commitsSat 9:00 — 2 commitsSat 10:00 — 0 commitsSat 11:00 — 9 commitsSat 12:00 — 8 commitsSat 13:00 — 4 commitsSat 14:00 — 1 commitsSat 15:00 — 0 commitsSat 16:00 — 1 commitsSat 17:00 — 2 commitsSat 18:00 — 4 commitsSat 19:00 — 4 commitsSat 20:00 — 2 commitsSat 21:00 — 2 commitsSat 22:00 — 0 commitsSat 23:00 — 0 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.

Who is committing

last 52 weeks
Maintainer commits477 (98%)
Community commits8 (2%)

485 commits in total over the last year.

DateListRankStars gained
Jul 10, 2026daily#22+2
  • affaan-m/ECC

    The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

    272.8K stars · JavaScript

  • react/react

    The library for web and native user interfaces.

    250.9K stars · JavaScript

  • DietrichGebert/ponytail

    Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.

    154.6K stars · JavaScript

  • vercel/next.js

    The React Framework

    143.2K stars · JavaScript

  • addyosmani/agent-skills

    Production-grade engineering skills for AI coding agents.

    101.1K stars · JavaScript

  • Leonxlnx/taste-skill

    Taste-Skill - gives your AI good taste. stops the AI from generating boring, generic slop

    92.6K stars · JavaScript