Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,6 @@ Flags:
| Flag | |
|---|---|
| `--project <glob...>` | TypeScript projects to lint |
| `--vue-project <glob...>` | Vue projects |
| `--vue-vine-project <glob...>` | Vue Vine projects |
| `--mdx-project <glob...>` | MDX projects |
| `--astro-project <glob...>` | Astro projects |
| `--ts-macro-project <glob...>` | TS Macro projects |
| `--filter <glob...>` | Restrict to matching files |
| `--fix` | Apply fixes |
| `--force` | Ignore cache |
Expand All @@ -217,28 +212,21 @@ TSSLint produces diagnostics and edits — it does not format. Run dprint or Pre

## Framework support

The `--*-project` flags wire in [Volar](https://volarjs.dev/) language plugins so framework files (Vue SFCs, MDX, Astro components, etc.) are virtualized as TypeScript before linting. Anything `tsserver` can see, TSSLint can lint.
Since v4, framework files (`.vue`, `.astro`, `.mdx`, `.svelte`, …) are checked through TypeScript 7.1's **content mapper** — the same mechanism `tsc` uses — instead of Volar language plugins. Declare the mappers in `tsconfig.json`; TSSLint picks them up with the project:

```
.vue ──┐
.mdx ──┤ ┌──────────────┐ ┌──────────────────┐
.astro──┼───▶│ Framework │───▶│ tsserver │───▶ diagnostics
.ts ──┘ │ adapters │ │ │ in editor
│ │ │ TypeChecker │
│ ─▶ virtual │ │ + │
│ TS file │ │ TSSLint plugin │
└──────────────┘ └──────────────────┘
```jsonc
{
"contentMappers": [
{ "package": "vue-content-mapper", "extensions": [".vue"] }
]
}
```

Each flag resolves the language plugin from your project's `node_modules`, so you must install the corresponding package:
Rules run against the transformed TypeScript, and diagnostics and fixes are mapped back to the original file through the mapper's span map. Fixes are only offered on exact (verbatim) spans — the same restriction `tsc` applies to edits.

| Flag | Required package(s) |
|---|---|
| `--vue-project` | `@vue/language-core` or `vue-tsc` |
| `--vue-vine-project` | `@vue-vine/language-service` or `vue-vine-tsc` |
| `--mdx-project` | `@mdx-js/language-service` |
| `--astro-project` | `@astrojs/ts-plugin` |
| `--ts-macro-project` | `@ts-macro/language-plugin` or `@ts-macro/tsc` |
The v3 flags `--vue-project`, `--vue-vine-project`, `--mdx-project`, `--astro-project`, and `--ts-macro-project` are gone; the mapper configuration in `tsconfig.json` replaces them. See [docs/migration-v4.md](docs/migration-v4.md).

> **Availability**: content mapper support activates once `typescript-native-bridge` moves to tsgo 7.1. Until then the CLI checks plain TypeScript files only.

## Importing ESLint, TSLint, or TSL rules

Expand Down Expand Up @@ -335,8 +323,9 @@ Build your own with the `Plugin` type from `@tsslint/types`.
## Requirements

- Node.js **22.6.0+** (uses `--experimental-strip-types` to load `tsslint.config.ts` directly — no transpile step)
- Any TypeScript version with Language Service Plugin support
- Not compatible with `typescript-go` (v7), which does not yet support Language Service Plugins
- The CLI bundles its own TypeScript engine ([`typescript-native-bridge`](https://github.com/johnsoncodehk/typescript-native-bridge), TS 7 / tsgo) — you no longer install or pin `typescript` to lint
- Not supported on musl-based systems (Alpine) — the bundled engine links a glibc native binary
- `@tsslint/typescript-plugin` still runs against a classic TypeScript tsserver; the TS 7 language server path is being rebuilt (see [docs/migration-v4.md](docs/migration-v4.md))

## License

Expand Down
91 changes: 91 additions & 0 deletions docs/migration-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Migrating to TSSLint v4

v4 moves the lint engine onto TypeScript 7 and replaces the Volar-based
framework support with TypeScript's own content mapper.

## Breaking changes

### 1. The CLI bundles its own TypeScript engine

`@tsslint/cli` no longer declares `typescript` as a peer dependency. It depends
on [`typescript-native-bridge`](https://github.com/johnsoncodehk/typescript-native-bridge)
(exact-pinned), which keeps the classic `typescript` API surface but runs the
TS 7 (tsgo) checker in-process.

- You no longer need to install or pin `typescript` for linting, and package
manager overrides that redirected `typescript` to the bridge are no longer
required for TSSLint itself.
- Diagnostics come from the tsgo checker. On a real project the output can
differ from TS 6.x in edge cases — that difference is the engine, not a
TSSLint regression.
- The bridge does not support custom module resolvers or JS custom transformers.
If your setup remaps imports to different files on disk, those remappings are
not honoured.

### 2. Framework flags are gone

The Volar integration — and with it the five project flags — has been removed:

| v3 | v4 |
|---|---|
| `tsslint --project tsconfig.json --vue-project tsconfig.json` | declare `contentMappers` in `tsconfig.json`, then `tsslint --project tsconfig.json` |
| `--vue-vine-project`, `--mdx-project`, `--astro-project`, `--ts-macro-project` | same — mapper entries in `tsconfig.json` |

There is no replacement flag; the tsconfig is the single source of truth.

### 3. Platform requirements

- Node.js **22.6.0+** (unchanged) — the bridge itself needs ≥ 20.19.
- **musl-based systems (Alpine) are not supported.** The bridge links a glibc
native binary; run the lint step in a glibc image and copy results into your
Alpine deploy stage.
- Peak memory on checker-heavy runs rises to roughly 1.9× the previous engine.

## Framework projects

Framework files are checked through TypeScript 7.1's content mapper. Add the
mapper package for your framework to `tsconfig.json`:

```jsonc
{
"compilerOptions": { },
"contentMappers": [
{ "package": "vue-content-mapper", "extensions": [".vue"], "options": { } }
],
"include": ["src"]
}
```

The mapper package declares how it runs in its own `package.json`:

```jsonc
{
"typescript": {
"contentMapper": {
"exec": ["node", "dist/server.js"],
"compilerOptions": ["module", "jsx", "jsxImportSource"]
}
}
}
```

Notes that affect what you can lint:

- Rules run on the transformed TypeScript. Diagnostics and fixes are mapped back
to the original file through the mapper's span map; **fixes are only offered
on exact (verbatim) spans**, matching the edit-safety rule `tsc` applies.
- The protocol has no per-diagnostic-code filtering and does not drop diagnostics
on unmapped (synthetic) regions — both are deliberate design choices upstream.
- `tsc` requires `--runExternalCode` to execute mappers; TSSLint runs them as
part of loading the project.

**Availability**: content mapper support activates once `typescript-native-bridge`
rebases onto tsgo 7.1. Until then the CLI checks plain TypeScript files only.
Mapper packages per framework follow their own ecosystems' adoption.

## Editors

`@tsslint/typescript-plugin` still targets a classic TypeScript tsserver and is
unaffected by the CLI change. The TS 7 language server path (LSP middleware plus
content mapper registration) is being rebuilt on the TS 7.1 APIs; until that
lands, editor diagnostics for framework files keep using the previous setup.
3 changes: 0 additions & 3 deletions fixtures/meta-frameworks/fixture.astro

This file was deleted.

6 changes: 0 additions & 6 deletions fixtures/meta-frameworks/fixture.mdx

This file was deleted.

3 changes: 0 additions & 3 deletions fixtures/meta-frameworks/fixture.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions fixtures/meta-frameworks/fixture.vine.ts

This file was deleted.

3 changes: 0 additions & 3 deletions fixtures/meta-frameworks/fixture.vue

This file was deleted.

12 changes: 0 additions & 12 deletions fixtures/meta-frameworks/package.json

This file was deleted.

7 changes: 0 additions & 7 deletions fixtures/meta-frameworks/tsconfig.json

This file was deleted.

7 changes: 0 additions & 7 deletions fixtures/meta-frameworks/tsslint.config.ts

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"format": "dprint fmt",
"lint": "packages/cli/bin/tsslint.js --project {tsconfig.json,packages/*/tsconfig.json}",
"lint:fix": "npm run lint -- --fix && npm run format",
"lint:fixtures": "packages/cli/bin/tsslint.js --project fixtures/*/tsconfig.json --vue-project fixtures/meta-frameworks/tsconfig.json --mdx-project fixtures/meta-frameworks/tsconfig.json --astro-project fixtures/meta-frameworks/tsconfig.json --ts-macro-project fixtures/meta-frameworks/tsconfig.json"
"lint:fixtures": "packages/cli/bin/tsslint.js --project fixtures/*/tsconfig.json"
},
"devDependencies": {
"@lerna-lite/cli": "latest",
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @tsslint/cli

Command-line runner for TSSLint. Lints TypeScript projects — and Vue / Vue Vine / MDX / Astro / TS Macro projects via Volar language plugins — in CI or from the terminal.
Command-line runner for TSSLint. Lints TypeScript projects in CI or from the terminal.

## Usage

Expand All @@ -16,4 +16,4 @@ npx tsslint --project 'packages/*/tsconfig.json' --filter 'src/**/*.ts'

Run `tsslint --help` for the full flag list.

See the [root README](../../README.md) for framework project flags (`--vue-project`, `--mdx-project`, …), caching behavior, and how diagnostics are emitted.
See the [root README](../../README.md) for caching behavior and how diagnostics are emitted.
Loading
Loading