Blazing fast CLI type-checker for Svelte projects. Drop-in replacement for svelte-check — compatible flags, byte-identical diagnostics, same exit codes. Single Rust binary, powered by tsgo, incremental via tsbuildinfo. Built for AI agents, CI/CD, and pre-commit hooks that actually stay enabled.
Not an LSP, CSS linter, or formatter.
Measured on a SvelteKit + TypeScript monorepo with
1359 .svelte files (Svelte 5 runes), M1 Pro 8C, mean of 2 runs each:
svelte-check-native --tsconfig tsconfig.json --diagnostic-sources 'ts,svelte'
tool cold warm dirty speedup errors/warnings/problems
──────────────────────────────────────────────────────────────────────────────────────
svelte-check-native 1.8s 1.0s 0.9s 41x 0/49/17
svelte-check 40.0s 41.0s 41.6s 1.0x 0/49/17
svelte-check --tsgo 18.3s 18.6s 17.9s 2.9x 1/49/18
svelte-check-rs 12.2s 5.5 4.4s 7.5x 732/44/261
Diagnostic counts match svelte-check with same flags.
npm i -D svelte-check-native @typescript/native-preview
@typescript/native-preview is the tsgo binary — required at check
time, never imported at runtime.
npx svelte-check-native --workspace .
Or add it to package.json:
{
"scripts": {
"check": "svelte-check-native --workspace ."
}
}
Same flags as svelte-check. See npx svelte-check-native --help.
Single Rust binary. Each .svelte file flows through a handful of
crates in one process:
| Crate | What it does |
|---|---|
parser |
Parses .svelte source into a Svelte-5 AST (script + template). |
analyze |
Builds a SemanticModel — runes, prop shapes, bindings, scope — used by emit and lint. |
emit |
Generates the .svelte.ts overlay tsgo will type-check. Imports rewritten so tsgo lands on it. |
svn-lint |
Native Rust port of svelte/compiler's warning pass. Covers all known codes; no subprocess. |
svelte-compiler |
Fallback bridge to the user's svelte/compiler over a persistent bun/node worker pool. |
typecheck |
Owns the tsgo overlay tsconfig + the tsbuildinfo cache; invokes tsgo; maps diagnostics back. |
core |
Shared types (spans, diagnostics, position maps) + the canonical TsConfig struct. |
cli |
Entrypoint. Flag parsing, file discovery, output formatting, exit codes. |
Every flag not listed below behaves the same as svelte-check.
--svelte-warnings <mode> How to source Svelte compiler warnings:
native | bridge
native: rust port faster
bridge: js bridge same as svelte-check, slower by 1.5-2s
--timings Phase-by-phase wall-clock breakdown
--debug-paths Print resolved binaries, exit
--tsgo-version Print tsgo version, exit
--tsgo-diagnostics Print tsgo's perf/memory stats after the run
--emit-ts Print generated TypeScript per file, exit
--watch / --preserveWatchOutput — use watchexec
or your editor's file watcher externally.--no-tsconfig — errors out. A tsconfig is required.--incremental — always on. tsgo's tsbuildinfo handles it.--tsgo — always on. Classic tsc is not wired up.--diagnostic-sources css — accepted but no-op (a CSS language
service isn't bundled). Roadmap below.Run svelte-check-native --help for the full list.
Output defaults to machine when run from a coding-agent CLI:
CLAUDECODE=1 (Claude Code), GEMINI_CLI=1 (Gemini CLI), or CODEX_CI=1 (OpenAI Codex CLI).
TSGO_BIN — override tsgo discovery; accepts an absolute path to a
platform-native tsgo binary. Useful when @typescript/native-preview
isn't in node_modules (e.g. a monorepo where tsgo lives elsewhere).SVN_BRIDGE_WORKERS — number of svelte/compiler worker
subprocesses. Default cores/2, capped at 8; tracks the perf-core
count on Apple Silicon. Override if you hit IPC contention on very
large core counts.CLAUDECODE / GEMINI_CLI / CODEX_CI — any set forces machine
output for agent-friendly parsing.0 — no errors (and no warnings if --fail-on-warnings)1 — errors detected (or warnings with --fail-on-warnings)2 — invocation error (bad flag, missing tsconfig, tsgo not found)Stale errors after editing tsconfig.json or path aliases — wipe
the cache: rm -rf node_modules/.cache/svelte-check-native and re-run.
The overlay config is regenerated from your live tsconfig on every
run, but tsgo's tsbuildinfo can hold onto stale resolution state.
TS2321 "Excessive stack depth" on your own types — usually a
UnionToRecord<T> that round-trips through UnionToTuple<T>[number].
Iterate T directly in the mapped-type key instead.
svelte2tsx
/ svelte-check
— transpiler + CLI whose output shape and flags we
match. The .v5 fixture corpus from svelte2tsx is our parity gate.@typescript/native-preview.MIT