[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-92732":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":12,"openIssues":12,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":14,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":15,"rankGlobal":9,"rankLanguage":9,"license":16,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":9,"pushedAt":9,"updatedAt":21,"readmeContent":22,"aiSummary":23,"trendingCount":13,"starSnapshotCount":13,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},92732,"typescript-native-bridge","johnsoncodehk\u002Ftypescript-native-bridge","johnsoncodehk","A typescript-shaped drop-in backed by typescript-go (tsgo) over an in-process cgo NAPI\u002FFFI bridge — no IPC.",null,"TypeScript",79,1,0,12,42.1,"Apache License 2.0",false,"master",true,[],"2026-07-22 04:02:06","# typescript-native-bridge (TNB)\n\n> **Status:** Experimental. Published on npm as [`typescript-native-bridge`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Ftypescript-native-bridge).\n\n**A faster `typescript` you can drop into any project** (measure on your repo; no fixed speedup guarantee).\n\nSwap the `typescript` package for this fork and keep using `tsc`, `vue-tsc`, ESLint, and your\neditor as before. Type-checking runs on **tsgo** (Microsoft's Go TypeScript compiler) instead\nof JavaScript. You do **not** need to learn tsgo, change imports, or add per-tool config.\n\n---\n\n## Why TNB exists\n\nTNB is a **drop-in `typescript` replacement** — not a separate `tsgo` CLI, not a new\nLSP. One `typescript` override accelerates every tool that calls `getTypeChecker()` through\nthe standard Compiler API.\n\n### Three problems one override fixes\n\n**1. `vue-tsc` cannot use standalone `tsgo`**\n\n`vue-tsc` is built on the `typescript` programmatic API + Volar hooks (`extraFileExtensions`,\nvirtual `getSourceFile` for `.vue`, `createProgram` wrapping). Standalone `tsgo` \u002F `tsgo\nLSP` does not speak that protocol — you cannot speed up `vue-tsc` by swapping the CLI to\n`tsgo`. TNB keeps `vue-tsc` unchanged and routes `createProgram` → `createTsgoProgram`,\nfeeding Volar virtual content to Go via in-process overlays.\n\n**2. ESLint + typescript-eslint type-aware rules are checker-bound**\n\n`@typescript-eslint\u002Fparser` imports `typescript` and calls `createProgram` \u002F\n`getTypeChecker()` for type-aware rules. The bottleneck is the JS checker, not ESLint's\nAST walk. TNB makes the parser pick up the fork automatically — no eslint config changes,\nno separate `tsgo` lint pass.\n\n**3. Editors need `tsserver` + Language Service Plugins (not tsgo LSP)**\n\nVolar (`@vue\u002Ftypescript-plugin`) runs as a **tsserver LS Plugin**. Microsoft's tsgo LSP\npreview does not support that plugin model — migrating the editor means losing `.vue`\nintegration. TNB keeps **stock `tsserver` + plugin host**, swapping only the checker\nbackend to Go in-process.\n\n### What this means in practice\n\n| Tool | Still uses | Checker engine |\n|---|---|---|\n| `vue-tsc` \u002F `tsc` | `typescript` API (`_tsc.js`) | tsgo |\n| `tsserver` \u002F VS Code | `typescript` + LS Plugins | tsgo |\n| `@typescript-eslint\u002Fparser` | `typescript` API | tsgo |\n\nCompare with `@typescript\u002Fnative-preview`: separate `tsgo` binary, change scripts, editor\nuses experimental tsgo LSP — **does not** cover the three rows above with one override.\n\n---\n\n## 10-minute checklist\n\nUse this if you just want to try TNB on an existing project:\n\n- [ ] Add a `typescript` override (see below)\n- [ ] Run `pnpm install` \u002F `npm install`\n- [ ] Run your usual typecheck (`vue-tsc`, `tsc`, or `nuxi typecheck`)\n- [ ] Confirm the **TNB ACTIVE** banner appears on stderr (first run per process)\n- [ ] **Editor:** set `typescript.tsdk` and switch to the workspace TypeScript version (see [Editor \u002F tsserver](#editor--tsserver-tsdk))\n- [ ] If no banner → see [Troubleshooting](#troubleshooting)\n\n---\n\n## Quick start\n\n### pnpm (monorepos)\n\nPut the override in **`pnpm-workspace.yaml`** at the repo root:\n\n```yaml\n# pnpm-workspace.yaml\noverrides:\n  typescript: npm:typescript-native-bridge@\u003Cversion>\n```\n\n```bash\npnpm install\npnpm exec vue-tsc -b --noEmit    # or your project's typecheck script\n```\n\nIf packages use `catalog:typescript`, update the **catalog entry** as well (see\n[Nuxt \u002F Vue \u002F monorepo notes](#nuxt--vue--monorepo-notes)).\n\n### npm\n\n```jsonc\n\u002F\u002F package.json\n{\n  \"overrides\": {\n    \"typescript\": \"npm:typescript-native-bridge@\u003Cversion>\"\n  }\n}\n```\n\n### yarn\n\n```jsonc\n\u002F\u002F package.json\n{\n  \"resolutions\": {\n    \"typescript\": \"npm:typescript-native-bridge@\u003Cversion>\"\n  }\n}\n```\n\n### Local path (developing TNB or pinning a git checkout)\n\n```yaml\n# pnpm-workspace.yaml\noverrides:\n  typescript: link:..\u002Ftypescript-native-bridge\n```\n\nBuild the fork first (`npm run setup` in the TNB repo). See [Developing TNB](#developing-tnb-contributors).\n\nAfter any override change: **reinstall dependencies**. The override applies repo-wide —\n`vue-tsc`, `@typescript-eslint\u002Fparser`, and other transitive `typescript` users all pick\nup the fork.\n\n---\n\n## How to tell it's working\n\nOn the **first** type-check in a process, TNB prints this banner to **stderr**:\n\n```\n┌─────────────────────────────────────────────────────────┐\n│  ✅  TNB ACTIVE — `typescript` is the tsgo-backed fork  │\n└─────────────────────────────────────────────────────────┘\n```\n\n**No banner = stock `typescript` is still loaded.** See [Troubleshooting](#troubleshooting).\n\nQuick sanity check:\n\n```bash\nnode -e \"console.log(require.resolve('typescript'))\"\n# should point at typescript-native-bridge, not node_modules\u002Ftypescript@5.x\n```\n\n---\n\n## What you get\n\n| | Stock `typescript` | TNB |\n|---|---|---|\n| Import | `import * as ts from \"typescript\"` | Same |\n| CLI | `tsc`, `vue-tsc`, `nuxi typecheck` | Same commands |\n| Per-tool config | — | None |\n| Checker engine | JavaScript | Go (tsgo), in-process |\n\n```\nyour tool  →  typescript (fork)  →  tsgo (Go)\n              same public API         type-checking\n                    └── in-process bridge (no child process, no IPC)\n```\n\n**API compatibility:** Existing `tsc` \u002F `vue-tsc` \u002F ESLint workflows work without code\nchanges. The checker is implemented by tsgo internally; tools that depend on deep\nTypeScript internals or custom emit paths should be validated separately.\n\n---\n\n## Nuxt \u002F Vue \u002F monorepo notes\n\n### pnpm catalog + overrides\n\nIf your monorepo uses a **catalog** and any package depends on `typescript` via\n`catalog:`, update the catalog entry **as well as** `overrides:` — otherwise those\npackages may still resolve stock TypeScript even when root `overrides` is set:\n\n```yaml\n# pnpm-workspace.yaml\ncatalog:\n  typescript: link:..\u002Ftypescript-native-bridge\noverrides:\n  typescript: link:..\u002Ftypescript-native-bridge\n```\n\n> **Monorepo tip:** Prefer workspace `overrides` only. A root `pnpm add -D typescript@link:...`\n> alone often does **not** replace `vue-tsc`'s transitive `typescript`.\n\n### Nuxt projects\n\nTypical flow:\n\n```bash\npnpm exec nuxi prepare          # generate .nuxt types first\npnpm exec nuxi typecheck        # or your package.json \"typecheck\" script\n```\n\n### Vue \u002F Volar \u002F SFC\n\n**Supported**\n\n- `import App from '.\u002FApp.vue'` resolves to the `.vue` file itself\n- Volar **virtual TypeScript** (content injected via `getSourceFile` when the file\n  isn't on disk) via overlay\n- `.vue`, `.svelte`, `.astro`, `.mdx`, etc. through the standard `extraFileExtensions`\n  contract — no hard-coded `.vue` special case\n- `allowArbitraryExtensions` inferred `true` in tsgo when host extra extensions are\n  present and tsconfig leaves the option unset (explicit `false` opts out)\n\n**Not supported**\n\n- Custom `resolveModuleNames` \u002F `resolveModuleNameLiterals` that remap an import to a\n  **different physical file** (bridge is synchronous JS→Go; tsgo cannot call back into JS\n  resolvers)\n- Explicit `allowArbitraryExtensions: false` in tsconfig → normal `TS6263` (opt-out)\n\n### Editor \u002F tsserver (tsdk)\n\nCLI typecheck (`vue-tsc`, `tsc`) picks up TNB automatically after the override. **The IDE\ndoes not** — VS Code \u002F Cursor ship their own TypeScript and only use your fork when you\npoint **`typescript.tsdk`** at the workspace install and opt in to the workspace version.\n\nAfter `pnpm install`, `node_modules\u002Ftypescript` **is** TNB (same layout as stock\n`typescript`: `lib\u002Ftsserver.js`, `lib\u002Ftypescript.js`, …). The editor must load that\n`tsserver`, not the built-in one.\n\n**1. Add workspace settings** (commit `.vscode\u002Fsettings.json` for the team):\n\n```jsonc\n\u002F\u002F .vscode\u002Fsettings.json — VS Code and Cursor\n{\n  \"typescript.tsdk\": \"node_modules\u002Ftypescript\u002Flib\",\n  \"typescript.enablePromptUseWorkspaceTsdk\": true\n}\n```\n\nUse a path relative to the **workspace folder** that contains `node_modules` (monorepo:\nusually the repo root). With pnpm overrides this resolves to TNB's `lib\u002F` even when the\nphysical path is a symlink.\n\n**2. Switch to the workspace version (required once per machine \u002F workspace)**\n\nCommand Palette → **`TypeScript: Select TypeScript Version`** → **Use Workspace Version**.\n\nVS Code deliberately does not run workspace `tsserver` until you confirm (security). The\nprompt appears on first open if `typescript.enablePromptUseWorkspaceTsdk` is set; otherwise\nrun the command manually.\n\n**3. Verify**\n\n- Status bar \u002F **TypeScript: Select TypeScript Version** should show a path under\n  `node_modules\u002Ftypescript\u002Flib`, not \"VS Code's Version\".\n- Open a `.ts` file and trigger type-checking; **View → Output → TypeScript** may show\n  **TNB ACTIVE** on first project load (same banner as CLI).\n- Vue\u002FNuxt: keep `@vue\u002Ftypescript-plugin` in `tsconfig` `compilerOptions.plugins` as today\n  — it runs as a **tsserver LS Plugin** on this fork; no separate tsgo LSP.\n\n| Path | Bundle | Used by |\n|---|---|---|\n| `lib\u002F_tsc.js` | CLI | `tsc`, `vue-tsc -b` |\n| `lib\u002Ftsserver.js` → `lib\u002Ftypescript.js` | Language service | IDE, `tsserver`, LS Plugins |\n\n### CLI vs editor (summary)\n\n| | CLI | IDE |\n|---|---|---|\n| Needs override | Yes | Yes (same `node_modules\u002Ftypescript`) |\n| Extra config | No | **`typescript.tsdk` + Use Workspace Version** |\n| Vue LS Plugin | via `vue-tsc` \u002F program API | via forked `tsserver` + `@vue\u002Ftypescript-plugin` |\n\n---\n\n## CI verification\n\n```bash\n# 1. Confirm resolved package\nnode -e \"console.log(require.resolve('typescript'))\"\n\n# 2. Typecheck + require banner (adjust command to your project)\npnpm exec vue-tsc -b --noEmit 2>&1 | tee \u002Ftmp\u002Ftsc.log\ngrep -F 'TNB ACTIVE' \u002Ftmp\u002Ftsc.log || { echo 'TNB not active'; exit 1; }\n```\n\n**Linux CI:** The loader supports `bridge.so` \u002F `bridge.dll`, but this repo may\nonly ship `bridge.dylib` until you build or publish per-platform binaries. Run\n`npm run build:bridge` on the target OS, or ensure your package artifact includes\n`native\u002Fbridge.*` for the runner (see [Platform support](#platform-support)).\n\nDebug slow runs: `TSGO_PROFILE=1` prints a `[tsgo-profile]` timing summary to stderr on process exit (not a `.cpuprofile` file).\n\n---\n\n## Troubleshooting\n\n### No banner appears\n\n| Check | Action |\n|---|---|\n| Override at workspace **root** | Monorepo: `pnpm-workspace.yaml`, not a leaf package |\n| pnpm 11 | Move `package.json` → `pnpm.overrides` to `pnpm-workspace.yaml` → `overrides:` (pnpm 11 no longer reads the `pnpm` field — silently ignored) |\n| `catalog:` pin | Update catalog **and** overrides (see above) |\n| Stale install | `pnpm install` again; clear CI cache if needed |\n| Wrong resolution | `node -e \"console.log(require.resolve('typescript'))\"` |\n\n### CLI works, editor doesn't (or vice versa)\n\n- **CLI OK, IDE not:** add [Editor \u002F tsserver (tsdk)](#editor--tsserver-tsdk) settings and\n  run **TypeScript: Select TypeScript Version → Use Workspace Version**. Override alone is\n  not enough for the editor.\n- **IDE OK, CLI not:** run `node -e \"console.log(require.resolve('typescript'))\"` — should\n  point at TNB. Reinstall after changing overrides.\n- CLI and IDE must both resolve the same `node_modules\u002Ftypescript` (same override at\n  monorepo root).\n\n### Type errors differ from stock TypeScript\n\nTNB is experimental; tsgo parity with JS TypeScript is not 100%. Pin a version, diff\nresults, and report gaps. This is expected during early adoption.\n\n### Missing native bridge\n\nError mentioning `bridge.dylib` \u002F `bridge.so` \u002F `bridge.dll` → run `npm run setup` in\nthis repo or ensure published artifacts include your platform.\n\n---\n\n## Platform support\n\n| OS | Native library | Notes |\n|---|---|---|\n| macOS | `native\u002Fbridge.dylib` | Primary dev target; may be the only prebuilt binary in a dev clone |\n| Linux | `native\u002Fbridge.so` | Build with `npm run build:bridge` on Linux for CI |\n| Windows | `native\u002Fbridge.dll` | Supported by loader; build on Windows |\n\nEnd users of a **published** package need prebuilt binaries per platform. Contributors\nbuild locally with Go + a C toolchain (`npm run build:bridge`).\n\n---\n\n## Uninstall \u002F rollback\n\nRemove the `typescript` override from `pnpm-workspace.yaml` \u002F `package.json`, reinstall,\nand confirm:\n\n```bash\npnpm install\nnode -e \"console.log(require.resolve('typescript'))\"   # should be stock typescript@5.x\n```\n\nNo source changes in your app are required to roll back.\n\n---\n\n## FAQ\n\n**Do I need to change my code?**  \nNo.\n\n**Do I configure `vue-tsc` or ESLint separately?**  \nNo. They import `typescript`; one override covers them.\n\n**Is this the same as `@typescript\u002Fnative-preview`?**  \nNo. TNB replaces the full `typescript` package with an in-process Go bridge and Volar\u002FSFC\nintegration. `@typescript\u002Fnative-preview` ships the separate `tsgo` CLI (and preview JS\nAPI) alongside stock `typescript` — you change scripts to call `tsgo`, not `tsc`.\n\n**How much faster is it?**  \nDepends on project size and shape; large `vue-tsc -b` workloads are the main target.\nMeasure on your repo with and without the override.\n\n---\n\n## Developing TNB (contributors)\n\n> End users can skip this section. Consuming a **prebuilt** clone (with `lib\u002F` +\n> `native\u002Fbridge.*` already present) does not require Go. Building TNB from source\n> in this repo requires Go, submodules, and `npm run setup`.\n\n### First-time setup\n\n```bash\ngit clone --recurse-submodules \u003Crepo>\ncd typescript-native-bridge\nnpm run setup    # submodules + vendor JS + native bridge + lib\u002F\n```\n\n### All scripts\n\n| Script | Purpose |\n|---|---|\n| `setup` | Full first-time build (everything below) |\n| `build:lib` | **Daily:** overlay → compile → LKG (~6s) |\n| `build:ts` | Cold build (+ `npm install` in typescript submodule) |\n| `build:js` | Compile `typescript-go` native-preview vendor (needed for bridge API types) |\n| `build:bridge` | Rebuild Go `native\u002Fbridge.{dylib,so,dll}` |\n| `patch:ts` | Apply `patches\u002Ftypescript\u002F` to submodule |\n| `patch:tsgo` | Apply `patches\u002Ftypescript-go\u002F` to submodule |\n| `refresh` | Re-apply both patch trees and run `check:lib` |\n| `save-ts-patches` | Save typescript submodule changes → `patches\u002Ftypescript\u002F` |\n| `save-patches` | Save typescript-go submodule changes → `patches\u002Ftypescript-go\u002F` |\n| `check:lib-sync` | Verify overlay \u002F submodule \u002F `lib\u002F` are aligned |\n| `check:enums` | Validate TS↔Go enum remapping tables |\n\n### Two patch trees, three artifact families\n\n```\npatches\u002Ftypescript\u002Foverlay\u002F     ← TypeScript-side changes (edit here)\npatches\u002Ftypescript-go\u002Foverlay\u002F  ← Go bridge changes (edit here)\n        ↓ patch + build\nlib\u002F          JS bundles (typescript.js + _tsc.js)\nnative\u002F       platform bridge binary\nvendor\u002F       native-preview JS (from build:js)\n```\n\n**TypeScript overlay workflow**\n\n```\npatches\u002Ftypescript\u002Foverlay\u002F\n        ↓  npm run patch:ts   (also run by build:lib)\ntypescript\u002F submodule          ← do not edit by hand\n        ↓  npm run build:lib\nlib\u002Ftypescript.js              ← tsserver\nlib\u002F_tsc.js                    ← tsc, vue-tsc\n```\n\nNever hand-edit `lib\u002F*.js` or `typescript\u002Fsrc\u002F`. Always rebuild both bundles via\n`build:lib`. Run `npm run check:lib-sync` before committing.\n\n**Go \u002F bridge workflow**\n\n```\npatches\u002Ftypescript-go\u002Foverlay\u002F\n        ↓  npm run patch:tsgo\ntypescript-go\u002F submodule\n        ↓  npm run build:bridge\nnative\u002Fbridge.*\n```\n\nAfter editing either submodule working tree: `save-ts-patches` or `save-patches` before commit.\n\n`git status` will show `typescript` \u002F `typescript-go` as modified after `patch:ts` \u002F\n`patch:tsgo` — that is expected (patches are applied to the submodule working tree, not\ncommitted inside the submodule). Re-apply with `npm run refresh` after `git submodule update`.\n\n**Changing enums between TS and Go:** run `npm run check:enums`.\n\n---\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).\n\nThis package is a derivative work of [Microsoft TypeScript](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FTypeScript)\nand [microsoft\u002Ftypescript-go](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypescript-go).\n","typescript-native-bridge 是一个 TypeScript 编译器的零配置替换方案，通过 in-process cgo 桥接将标准 TypeScript API（如 createProgram、getTypeChecker）无缝路由至 Go 实现的 tsgo 编译器后端，避免 IPC 开销。核心特点是完全兼容现有工具链（tsc、vue-tsc、tsserver、TypeScript ESLint），无需修改代码、配置或构建脚本，仅需 npm 依赖覆盖即可启用。适用于追求类型检查性能提升的中大型 TypeScript 项目，尤其在 Vue\u002FSvelte 等需语言服务插件、或 ESLint 类型感知规则频繁调用 checker 的场景下效果显著。",2,"2026-07-10 02:30:17","CREATED_QUERY"]