@yielded/effect-tsrs
v0.2.3
Published
Native Effect diagnostics for TypeScript, powered by tsrs
Readme
Effect Diagnostics (tsrs)
A Rust port of the Effect Language Service diagnostics, powered by tsrs. Provides all 130 diagnostic rules for Effect V4 and Effect V3.
The port provides a command-line diagnostic runner and Oxlint type-aware linting.
Effect quick fixes, refactors, and completions are available in the upstream
@effect/tsgo language service.
Installation
Add @yielded/effect-tsrs to your project:
npm install --save-dev @yielded/effect-tsrsThen check your project:
npx effect-tsrs diagnostics --project tsconfig.jsonOr run it without adding a dependency:
npx @yielded/effect-tsrs diagnostics --project tsconfig.jsonRequires Node.js 22.14 or newer. Prebuilt binaries are available for macOS (Apple Silicon and Intel), Linux (ARM64 and x64), and Windows (x64). The compiler and TypeScript standard libraries are included; no Rust toolchain is needed.
Keep npm optional dependencies enabled so the binary for your platform is installed.
Existing @effect/language-service plugin options in tsconfig.json are respected.
See Plugin Options to configure diagnostics.
Oxlint integration
Install a supported Oxlint pair, then run it through the Rust adapter:
npm install --save-dev [email protected] [email protected]
npx effect-tsrs oxlint .Enable Effect rules in .oxlintrc.json. The effecttsgo namespace is retained for
compatibility with existing configurations:
{
"$schema": "./node_modules/@yielded/effect-tsrs/oxlint-schema.json",
"plugins": ["effecttsgo", "typescript"],
"rules": {
"effecttsgo/floating-effect": "error",
"effecttsgo/missing-star-in-yield-effect-gen": "error",
"typescript/no-floating-promises": "error"
}
}The adapter enables --type-aware automatically. Oxlint owns severities,
per-file overrides, ignore patterns, and suppression comments. All 130 Effect
rules run in Rust; other type-aware rules and --type-check use the installed
oxlint-tsgolint backend. Effect behavior options and source
directives remain supported; Oxlint rule selection overrides tsconfig diagnostic
severities. Effect code actions (quick fixes and suggested edits) and per-rule
profiling are not ported.
--threads N limits the compiler workers as well as Oxlint's frontend. Under an
explicit limit the Rust and Go backend passes run sequentially; --threads 1
also disables parallel parsing and checking. Without a limit, tsrs chooses its
checker count and the backends can run concurrently. The standalone diagnostics
command accepts --singleThreaded for single-threaded comparisons.
Presets are available as @yielded/effect-tsrs/oxlint-presets for JS/TS configs,
or through extends, for example:
["./node_modules/@yielded/effect-tsrs/oxlint-presets/recommended.json"].
For existing scripts or editor integrations that invoke Oxlint directly, run
npx effect-tsrs patch --oxlint, then use oxlint --type-aware normally.
npx effect-tsrs unpatch --oxlint restores the original package bytes. Reapply
after reinstalling dependencies. Patching refuses shared symlink targets outside
the project; effect-tsrs oxlint works without modifying installed packages.
Supported Oxlint and oxlint-tsgolint versions, along with the packaged frontend source, are pinned in the Oxlint metadata. The Effect backend is this Rust port. Linux Oxlint integration requires glibc; the standalone diagnostic CLI also works with musl.
From a source checkout, run npm run build:release && npm run prepare:oxlint,
then EFFECT_TSRS_BINARY="$PWD/target/release/effect-tsrs" node bin/effect-tsrs.js oxlint ..
Run npm run verify:oxlint for integration checks against Effect TSGO.
npm run verify:oxlint:all compares all 614 fixture projects through the headless
protocol, covering all 130 rules, including duplicate diagnostics and related ranges.
Standalone type-aware linter
The CLI reports Effect diagnostics using the defaults and project selection of
the supported @effect/tsgo version. It targets
configured root files and roots of referenced projects; imported files outside
those roots supply types but receive no Effect diagnostics. Shared roots use
the selected project's plugin configuration. See
project selection for reference loading,
overlap precedence, and file eligibility. Add it to your project scripts to run
the same check locally and in CI:
{
"scripts": {
"check": "effect-tsrs diagnostics --project tsconfig.json"
}
}Diagnostics can also be emitted as JSON for other tools:
npx effect-tsrs diagnostics --project tsconfig.json --format jsonThe exit status reflects Effect errors (and warnings with --strict). Add
--type-check to also report ordinary TypeScript diagnostics and include them in
the exit status. This explicitly enables the combined check used by earlier
effect-tsrs versions.
JSON contains separate diagnostics and typescriptDiagnostics arrays,
summary counts, and timings.
typescriptDiagnostics is populated by --type-check. The command
exits with 0 when there are no errors, 1 for project or diagnostic errors,
and 2 for invalid arguments. Warnings and suggestions do not fail the command
by default.
Use --strict to also exit with 1 when warnings are reported, matching
effect-tsgo diagnostics --strict:
npx effect-tsrs diagnostics --project tsconfig.json --strictThis only changes the exit code; warnings keep their severity in text and JSON output. Suggestions still do not fail the command.
Supported Package Versions
The current release is built and tested with the following versions:
| Component | Version |
| --- | --- |
| Effect | V3 (3.19.19) and V4 (4.0.2) in the rule matrix; V4 (4.1.0) in the CLI, configuration, project, Oxlint and package checks |
| TypeScript | 7.1.0-beta, bundled through tsrs |
| tsrs | 0.19.0, pinned in upstream.json |
| Effect diagnostic rules | @effect/[email protected] |
| Node.js | >=22.14 |
Diagnostic Status
All 130 rules below are implemented. The release passes 4,263/4,263 comparisons against upstream, including diagnostic messages, severities, ranges, and related information. Verification details.
Some rules are disabled by default or produce suggestions. Enable them or change their severity in Plugin Options. Rule descriptions and links below mirror the upstream README.
Refactor Status
Refactors and quick fixes are not implemented in this port. Use
@effect/tsgo for editor code actions.
Completion Status
Editor completions are not implemented in this port. See the upstream completion status.
Best Practices
Relationship to effect-tsgo and tsrs
Use effect-tsrs for project diagnostics in your terminal, scripts, and CI.
It runs the Effect rules on tsrs's inferred types and symbols.
@effect/tsgo provides the full editor language service, including quick fixes,
refactors, and completions. effect-tsrs is a standalone diagnostics CLI and
does not replace your editor's TypeScript language server or build command.
Version Pinning
Each release bundles a pinned tsrs compiler and its TypeScript standard libraries.
upstream.json records the compiler revision; see
Supported Package Versions for the Effect diagnostic
baseline. Updating a separate TypeScript installation does not change the compiler
used by effect-tsrs.
When to Upgrade
Upgrade @yielded/effect-tsrs when a release includes compiler fixes or Effect
diagnostics you need. npm installs the matching native package for your platform.
Plugin Options
Configure diagnostics in your existing tsconfig.json using the same
@effect/language-service plugin entry as upstream. By default, the CLI skips
Effect diagnostics for a project without a plugin entry. Pass --lspconfig '{}' to
explicitly activate upstream defaults without editing the project config.
{
"compilerOptions": {
"plugins": [
{
"name": "@effect/language-service",
// Enable Effect diagnostics. (default: true)
"diagnostics": true,
// Upstream tsc option; standalone diagnostics always includes suggestions.
"includeSuggestionsInTsc": true,
// Process disabled rules so source directives can re-enable them.
"skipDisabledOptimization": false,
// Prefer namespace or barrel imports for these packages.
"namespaceImportPackages": [],
"barrelImportPackages": [],
// Follow named reexports at package top level. (default: "ignore")
"topLevelNamedReexports": "ignore",
// Patterns used by deterministicKeys.
"keyPatterns": [
{ "target": "service", "pattern": "default", "skipLeadingPath": ["src/"] },
{ "target": "custom", "pattern": "default", "skipLeadingPath": ["src/"] }
],
"extendedKeyDetection": false,
// Minimum pipeable transformations for missedPipeableOpportunity.
"pipeableMinArgCount": 2,
// Permit selected unstable or experimental APIs.
"allowedUnstableApis": [],
"allowedExperimentalApis": [],
// Permit multiple versions of these packages.
"allowedDuplicatedPackages": [],
// Variants considered by effectFnOpportunity.
"effectFn": ["span"],
// Override rule defaults. Use {} to keep the defaults.
"diagnosticSeverity": {
"floatingEffect": "error",
"asyncFunction": "warning"
},
// Apply options to matching files.
"overrides": [
{
"include": ["test/**/*.ts"],
"options": {
"diagnosticSeverity": {
"asyncFunction": "off"
}
}
}
]
}
]
}
}Severity values are "off", "error", "warning", "suggestion", and
"message". Inherited configuration, per-file overrides, and source suppression
directives are supported:
// @effect-diagnostics-next-line floatingEffect:off
Effect.succeed(42)To select rules for a single run, also opting in when no plugin entry exists:
npx effect-tsrs diagnostics --project tsconfig.json --rules floatingEffect,asyncFunction
npx effect-tsrs diagnostics --project tsconfig.json --rules allExplicit severity settings and suppression directives still apply.
--rules none disables the source-file Effect pass. Use --lspconfig to replace
the plugin options for a command:
npx effect-tsrs diagnostics --project tsconfig.json \
--lspconfig '{"diagnosticSeverity":{"floatingEffect":"warning"}}'The allowedUnstableApis and allowedExperimentalApis options accept module
paths or individual exports:
{
"allowedUnstableApis": ["effect/http", "effect/rpc/RpcClient#make"],
"allowedExperimentalApis": ["my-package/Preview#make"]
}A module path permits that module and its descendants; #exportName permits
only that export. Matching is case-sensitive and respects path segments.
Per-file overrides replace these lists.
Import preferences can also vary by file:
{
"namespaceImportPackages": ["effect"],
"overrides": [
{
"include": ["src/legacy/**/*.ts"],
"options": {
"namespaceImportPackages": [],
"barrelImportPackages": ["effect"]
}
}
]
}Development
See the porting notes for source builds, verification, benchmarks, and release instructions, and the fixture guide for focused rule comparisons.
License
MIT. Rules and diagnostic descriptions are adapted from Effect-TS/tsgo. Compiler and dependency notices are included in THIRD-PARTY-NOTICES.
