# svelte-check-rs

A high-performance, Rust-powered diagnostic engine designed as a drop-in replacement for `svelte-check`.

> **Note:** This tool only supports **Svelte 5+**. For Svelte 4 or earlier, use the official [svelte-check](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check).

## Features

- 🚀 **Fast**: 10-100x faster than `svelte-check` through Rust's zero-cost abstractions and parallel processing
- ✅ **Accurate**: Matches `svelte-check` diagnostics, including Svelte compiler errors via bun
- 🔄 **Compatible**: Drop-in CLI replacement, identical output formats
- 🧩 **Preprocessor-aware**: Resolves effective Vite/Svelte config preprocessors and maps diagnostics back to their original sources
- 🔧 **Maintainable**: Clean separation of concerns, comprehensive test suite

## Installation

### npm (recommended)

```bash
npm install -D svelte-check-rs
```

The npm package uses platform-specific optional dependencies to provide the binary. If you install with `--no-optional`, re-enable optional dependencies or use the shell/PowerShell installers below.

Then add to your package.json scripts:

```json
{
  "scripts": {
    "check": "svelte-check-rs"
  }
}
```

Or run directly with npx:

```bash
npx svelte-check-rs
```

### macOS / Linux

```bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/pheuter/svelte-check-rs/releases/latest/download/svelte-check-rs-installer.sh | sh
```

### Windows (PowerShell)

```powershell
irm https://github.com/pheuter/svelte-check-rs/releases/latest/download/svelte-check-rs-installer.ps1 | iex
```

## Usage

```bash
# Check current directory
svelte-check-rs

# Check specific directory
svelte-check-rs --workspace ./my-project

# Watch mode
svelte-check-rs --watch

# Different output formats
svelte-check-rs --output json
svelte-check-rs --output machine
svelte-check-rs --output human-verbose
```

## Requirements

`svelte-check-rs` supports the released TypeScript 7 native compiler. For Svelte
and SvelteKit projects, keep TypeScript 6 installed for tooling that uses its
JavaScript API and install the native compiler alongside it:

```bash
npm install -D typescript@^6 @typescript/native@npm:typescript@^7.0.2
```

The checker resolves `@typescript/native` directly, so a shared `tsc` shim cannot
accidentally select TypeScript 6. A regular `typescript` installation at version
7 or later is also supported when your other tooling no longer needs the
TypeScript 6 API. Replacing TypeScript 6 outright can break SvelteKit type
generation; see the [upstream compatibility discussion](https://github.com/sveltejs/language-tools/issues/3063#issuecomment-5472405798).

Existing `@typescript/native-preview` installations remain supported, starting at
`7.0.0-dev.20260707.2` for consistent UTF-16 diagnostic columns. Install one of the
native compiler options explicitly; both npm peers are optional to allow either
choice. Compiler resolution walks up from `--workspace` through ancestor
`node_modules` directories.

Configured preprocessors are resolved with Vite-first precedence: effective options from
`vite.config.*` are used when vite-plugin-svelte or SvelteKit exposes them; otherwise
`svelte.config.{js,cjs,mjs,ts,mts}` is loaded. Inline Vite preprocessors and the
vite-plugin-svelte `configFile` option are supported. Preprocessor and imported config
dependencies are monitored in watch mode, including files outside the workspace.

### CLI Options

| Option | Description |
|--------|-------------|
| `--workspace <PATH>` | Working directory (default: `.`) |
| `--output <FORMAT>` | Output format: `human`, `human-verbose`, `json`, `machine` |
| `--color <MODE>` | Human output colors: `auto` (terminal only), `always`, `never`. Nonempty `NO_COLOR` disables colors. JSON and machine output stay plain. |
| `--tsconfig <PATH>` | Path to tsconfig.json |
| `--threshold <LEVEL>` | Minimum severity: `error`, `warning` |
| `--watch` | Watch mode |
| `--preserveWatchOutput` | Don't clear screen in watch mode |
| `--fail-on-warnings` | Exit with error on warnings |
| `--ignore <PATTERNS>` | Glob patterns to ignore |
| `--skip-tsgo` | Skip TypeScript type-checking |
| `--tsgo-version` | Show installed tsgo version + path |
| `--bun-version` | Show installed bun version + path |
| `--bun-update[=<VER>]` | Update bun to latest or specific version |
| `--debug-paths` | Show resolved binaries (tsgo, bun, svelte-kit) |

**Caching:** svelte-check-rs writes transformed files and tsgo incremental build info to `node_modules/.cache/svelte-check-rs/`. Cache invalidation is automatic: dependency changes (lockfiles, node_modules markers) clear the entire cache, and source file changes are handled via content-addressed writes.

## Project Structure

```
crates/
├── svelte-parser/        # Lexer + parser + AST types
├── source-map/           # Position tracking and mapping
├── svelte-transformer/   # Svelte → TypeScript transformation
├── svelte-diagnostics/   # A11y and component checks
├── tsgo-runner/          # tsgo process management
├── bun-runner/           # bun-managed Svelte compiler bridge
└── svelte-check-rs/      # CLI binary
```

## Development

```bash
# Build all crates
cargo build

# Run tests
cargo test

# Run clippy
cargo clippy --all-targets -- -D warnings

# Format code
cargo fmt
```

### Upstream parser parity sweep

To compare this parser against Svelte's full parser suites (`parser-modern` + `parser-legacy`),
run the optional ignored test with a local checkout of `sveltejs/svelte`:

```bash
git clone https://github.com/sveltejs/svelte.git /tmp/svelte
SVELTE_REPO=/tmp/svelte cargo test -p svelte-parser test_upstream_svelte_parser_samples -- --ignored
```

The harness runs every sample under `parser-modern` and `parser-legacy`, enabling loose mode
for samples whose directory name starts with `loose-` (mirroring upstream's runner).

## License

MIT License - see [LICENSE](LICENSE) for details.
