tsgolint-rust 0.0.0-stage → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present tunnckoCore and tsgolint-rust contributors
4
+ Copyright (c) 2025 July-present VoidZero Inc. & Contributors
5
+ Copyright (c) 2025 July typescript-eslint and other contributors
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,122 @@
1
- # Temporary Holding Version
1
+ # tsgolint-rust
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A Rust port of [oxc-project/tsgolint](https://github.com/oxc-project/tsgolint) (v7.0.2004), the type-aware linter that [oxlint](https://oxc.rs) runs for `--type-aware` and `--type-check`. It runs on [ts-rust](https://github.com/pingdotgg/ts-rust), a Rust port of TypeScript 7, instead of typescript-go.
4
+
5
+ It is a drop-in replacement. oxlint spawns it the same way, sends the same `headless` payload, and gets the same diagnostics, fixes and suggestions back. One ts-rust program and one checker pass give both the lint results and the type errors.
6
+
7
+ ## Status
8
+
9
+ - **Rules.** All 60 tsgolint rules, with their options, messages, fixes and suggestions.
10
+ - **tsgolint's own tests.** The 7,619 rule test cases of tsgolint's Go suite run with their expectations. 7,591 pass; the other 28 are skipped in tsgolint itself. The snapshots hold our own output on ts-rust; they differ from tsgolint's in one message, where TypeScript 7.1 orders a union differently.
11
+ - **e2e.** tsgolint's end-to-end suite passes, with the native binary and with the wasm build: 21 tests, plus 3 that run only on Windows or case-insensitive file systems.
12
+ - **oxlint.** oxlint 1.86.0 gives the same output on oxc's 25 tsgolint CLI fixtures with either binary, `--fix` included.
13
+ - **Real projects.** Compared with the Go binary on 12 projects (hono, TanStack Query, tRPC, h3, Effect, t3code, vercel/commerce). Every remaining difference comes from the TypeScript revision, from tsgolint's own run-to-run variation, or from the Effect diagnostics. [DIFFERENCES.md](DIFFERENCES.md) explains them.
14
+ - **wasm32-wasip1.** The WASI build runs on one thread, so it runs where threads are not available. Its output equals the native output.
15
+
16
+ ts-rust ports TypeScript 7.1.0-dev, a few months newer than the TypeScript 7.0 inside tsgolint. That accounts for most of the differences: some type strings in messages are cut short at another point, and a few diagnostics changed upstream.
17
+
18
+ ## Compatibility
19
+
20
+ tsgolint-rust has its own version numbers. Each release ports one tsgolint release (its rules and its `headless` protocol) on one ts-rust commit, and is tested with the oxlint versions below. [UPSTREAM.json](UPSTREAM.json) records the pins of the current source.
21
+
22
+ | tsgolint-rust | tsgolint rules and protocol | TypeScript | ts-rust | Tested with oxlint |
23
+ |---|---|---|---|---|
24
+ | 0.1.0 | [v7.0.2004](https://github.com/oxc-project/tsgolint/tree/v7.0.2004) | [`fed0bf24149f`](https://github.com/microsoft/TypeScript/commit/fed0bf24149f) (7.1.0-dev) | [`598e6416`](https://github.com/pingdotgg/ts-rust/commit/598e6416) | 1.86.0 |
25
+
26
+ ## Speed and memory
27
+
28
+ Lint with fixes and suggestions on real projects, all 60 rules, against the Go tsgolint on the same 12-core machine (median of 7 interleaved runs):
29
+
30
+ | Project | Files | Go | tsgolint-rust | Faster | Peak memory, Go / Rust |
31
+ |---|---:|---:|---:|---:|---:|
32
+ | TanStack Query core | 68 | 0.85 s | 0.51 s | 1.67x | 489 / 310 MB |
33
+ | TanStack Query React, with `--type-check` | 63 | 1.07 s | 0.50 s | 2.14x | 520 / 279 MB |
34
+ | h3 | 177 | 0.64 s | 0.49 s | 1.31x | 349 / 243 MB |
35
+ | hono | 312 | 1.91 s | 1.29 s | 1.48x | 811 / 498 MB |
36
+ | hono, with `--type-check` | 312 | 2.70 s | 1.21 s | 2.23x | 1060 / 507 MB |
37
+ | t3code contracts, with `--type-check` | 107 | 2.52 s | 0.94 s | 2.68x | 955 / 471 MB |
38
+ | t3code shared | 216 | 1.16 s | 0.72 s | 1.61x | 600 / 355 MB |
39
+ | Effect (`packages/effect/src`) | 516 | 3.77 s | 2.54 s | 1.48x | 1411 / 863 MB |
40
+ | t3code web chat | 224 | 5.13 s | 3.24 s | 1.58x | 2438 / 1469 MB |
41
+
42
+ Both run the same 4 checkers, so tsgolint-rust also uses less CPU: 10.3 s against 26.0 s of user time on t3code web chat. The native build uses jemalloc and fat LTO.
43
+
44
+ The wasm build needs about half the memory of the native build, because it keeps one checker alive at a time: 168 MB for TanStack Query core, 216 MB for hono with `--type-check`.
45
+
46
+ ## Effect diagnostics
47
+
48
+ ts-rust has the [Effect](https://effect.website) language service diagnostics built in. When a tsconfig enables the `@effect/language-service` plugin, `--type-check` also reports Effect's diagnostics (codes TS377xxx), from the same check.
49
+
50
+ ## Install
51
+
52
+ oxlint runs the `tsgolint` bin of the `oxlint-tsgolint` package. tsgolint-rust ships the same bin in the [`tsgolint-rust`](https://www.npmjs.com/package/tsgolint-rust) package, so you install it under the name `oxlint-tsgolint`. It picks its binary from one of `@tsgolint-rust/darwin-arm64`, `darwin-x64`, `linux-arm64`, `linux-x64` (static, for glibc and musl), `win32-arm64` and `win32-x64`.
53
+
54
+ oxlint declares an optional peer dependency on `oxlint-tsgolint@>=7.0.2003`. tsgolint-rust has its own versions, so tell your package manager to accept it, as below. Otherwise pnpm warns about an unmet peer and npm refuses to install.
55
+
56
+ With pnpm, alias it in `package.json`:
57
+
58
+ ```json
59
+ {
60
+ "devDependencies": {
61
+ "oxlint": "^1.86.0",
62
+ "oxlint-tsgolint": "npm:tsgolint-rust@0.1.0"
63
+ }
64
+ }
65
+ ```
66
+
67
+ and accept the version in `pnpm-workspace.yaml`:
68
+
69
+ ```yaml
70
+ peerDependencyRules:
71
+ allowedVersions:
72
+ "oxlint>oxlint-tsgolint": "*"
73
+ ```
74
+
75
+ With npm, add the same alias and an override that names it:
76
+
77
+ ```json
78
+ {
79
+ "devDependencies": {
80
+ "oxlint": "^1.86.0",
81
+ "oxlint-tsgolint": "npm:tsgolint-rust@0.1.0"
82
+ },
83
+ "overrides": {
84
+ "oxlint-tsgolint": "$oxlint-tsgolint"
85
+ }
86
+ }
87
+ ```
88
+
89
+ When another package brings `oxlint-tsgolint` in, override it everywhere instead: `overrides: { oxlint-tsgolint: npm:tsgolint-rust@0.1.0 }` in `pnpm-workspace.yaml` (with the peer rule above), or `"overrides": { "oxlint-tsgolint": "npm:tsgolint-rust@0.1.0" }` in npm's `package.json`. Going back to the Go tsgolint is removing the alias or the override.
90
+
91
+ Where no native build runs, or native binaries are not allowed, use the wasm build on Node's WASI: `"oxlint-tsgolint": "npm:@tsgolint-rust/wasm32-wasip1@0.1.0"`. It gives the same output on one thread, on Linux and macOS.
92
+
93
+ ## Build from source
94
+
95
+ ```sh
96
+ cargo build --release -p tsgolint-rust
97
+ OXLINT_TSGOLINT_PATH=$PWD/target/release/tsgolint pnpm exec oxlint --type-aware --type-check
98
+ ```
99
+
100
+ The wasm build, under [wasmtime](https://wasmtime.dev):
101
+
102
+ ```sh
103
+ cargo build --release --target wasm32-wasip1 -p tsgolint-rust
104
+ TSGOLINT_WASM=$PWD/target/wasm32-wasip1/release/tsgolint.wasm \
105
+ OXLINT_TSGOLINT_PATH=$PWD/tsgolint-rust/e2e/tsgolint-wasm.sh \
106
+ pnpm exec oxlint --type-aware --type-check
107
+ ```
108
+
109
+ ## How it works
110
+
111
+ | Crate | What it has |
112
+ |---|---|
113
+ | [`tsgolint-core`](tsgolint-core) | Program loading on ts-rust, the rule framework, the AST walk and the lint engine |
114
+ | [`tsgolint-rules`](tsgolint-rules) | The 60 rules, their shared helpers, and the test harness with tsgolint's cases and snapshots |
115
+ | [`tsgolint-rust`](tsgolint-rust) | The `tsgolint` binary: command line, `headless` protocol, tsconfig discovery, driver |
116
+ | [`tsgolint-compare`](tsgolint-compare) | A dev tool that runs the Go and Rust binaries on one payload and compares them |
117
+
118
+ Each tsconfig becomes one ts-rust program. ts-rust gives every file a checker, and each checker lives on its own thread. The engine sends each checker one job with the TypeScript diagnostics of its files, then one job that runs the rules on them. The binary streams the results to oxlint through tsgolint's 400 KB output buffer while the run goes on. [ARCHITECTURE.md](ARCHITECTURE.md) has the details.
119
+
120
+ ## Development
121
+
122
+ `pnpm exec turbo run check test build` runs fmt and clippy, the Rust tests and both e2e runs, and the release builds. The toolchain is in `rust-toolchain.toml`. ts-rust comes from [pingdotgg/ts-rust](https://github.com/pingdotgg/ts-rust), branch `main`. `Cargo.lock` pins the commit, and [UPSTREAM.json](UPSTREAM.json) records it with the TypeScript commit it ports and the ported tsgolint release. A daily workflow moves ts-rust when its compiler sources change, regenerates the snapshots and opens a pull request; another opens an issue when tsgolint releases a newer version.
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // Runs the tsgolint binary of the platform package that matches this
3
+ // machine (an optionalDependency of tsgolint-rust). Arguments, stdio and the
4
+ // exit code pass through, and a death by signal is passed on.
5
+ import { spawnSync } from 'node:child_process';
6
+ import { createRequire } from 'node:module';
7
+ import { constants } from 'node:os';
8
+ import process from 'node:process';
9
+
10
+ const require = createRequire(import.meta.url);
11
+ const target = `${process.platform}-${process.arch}`;
12
+ const exe = process.platform === 'win32' ? 'tsgolint.exe' : 'tsgolint';
13
+
14
+ let binary;
15
+ try {
16
+ binary = require.resolve(`@tsgolint-rust/${target}/${exe}`);
17
+ } catch {
18
+ console.error(
19
+ `tsgolint-rust: no binary for ${target}: @tsgolint-rust/${target} is not installed. ` +
20
+ 'Install again with optional dependencies, or use @tsgolint-rust/wasm32-wasip1.',
21
+ );
22
+ process.exit(1);
23
+ }
24
+
25
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
26
+ if (result.error) {
27
+ throw result.error;
28
+ }
29
+ if (result.signal) {
30
+ process.kill(process.pid, result.signal);
31
+ // Node ignores some signals (SIGPIPE): exit as a shell reports the death.
32
+ process.exitCode = 128 + (constants.signals[result.signal] ?? 0);
33
+ } else {
34
+ process.exitCode = result.status;
35
+ }
package/package.json CHANGED
@@ -1,6 +1,34 @@
1
1
  {
2
2
  "name": "tsgolint-rust",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.1",
4
+ "description": "A Rust port of tsgolint on ts-rust: the type-aware linter that oxlint runs for --type-aware and --type-check. Install it as oxlint-tsgolint.",
5
+ "keywords": [
6
+ "oxlint",
7
+ "tsgolint",
8
+ "typescript",
9
+ "linter",
10
+ "type-aware"
11
+ ],
12
+ "license": "MIT",
13
+ "author": "tunnckoCore",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/tunnckoCoreHQ/tsgolint-rust.git",
17
+ "directory": "npm/tsgolint-rust"
18
+ },
19
+ "bugs": "https://github.com/tunnckoCoreHQ/tsgolint-rust/issues",
20
+ "homepage": "https://github.com/tunnckoCoreHQ/tsgolint-rust#readme",
21
+ "type": "module",
22
+ "bin": {
23
+ "tsgolint": "bin/tsgolint.js"
24
+ },
25
+ "files": [
26
+ "bin"
27
+ ],
28
+ "engines": {
29
+ "node": ">=20"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
6
34
  }