skills/rstest-debugging/SKILL.md
Debug Rstest issues systematically, including performance regressions. First determine whether the slowdown is in build startup or test execution, then run controlled config or code experiments and compare before/after timings.
npx skillsauth add rstackjs/agent-skills rstest-debuggingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when Rstest is slower than expected, slower than Jest or Vitest, slower than a previous Rstest baseline, or when users report that tests spend a long time before starting.
The goal is not to guess a root cause from config names alone. First identify where time is being spent, then change one variable at a time and compare the result.
Before changing config or code:
node, jsdom, happy-dom, browser mode), and relevant worker settings.Common baseline commands:
npx rstest run path/to/test-file.test.ts
npx rstest --reporter=verbose path/to/test-file.test.ts
pnpm rstest path/to/test-file.test.ts
If the problem is reported as “there is a long pause before tests even start”, treat that as a build or startup hypothesis until measurements prove otherwise.
Split the investigation into one of these buckets:
Duration value is not enough to decide.Use these tools in order:
--trace when the time distribution is unclearnpx rstest run --trace
--trace produces a Perfetto-compatible trace with per-phase, per-suite, and per-case slices. Use it to answer: is the time concentrated in prepare or build phases, or inside test execution?
DEBUG=rstest for build-stage cluesDEBUG=rstest npx rstest run
Focus on:
dist/.rstest-tempnpx rstest --reporter=verbose
Use this to find the slow file, suite, or case before reaching for a profiler.
For jsdom and happy-dom, Rstest bundles third-party dependencies by default. That often explains reports like “Rstest is slow before tests even start”.
Check these first:
Run one experiment at a time, and rerun the exact same baseline command after each change.
For non-browser mode, try:
import { defineConfig } from '@rstest/core';
export default defineConfig({
testEnvironment: 'jsdom',
output: {
bundleDependencies: false,
},
});
Compare:
dist/.rstest-temp sizeIf only a few dependencies dominate the graph, prefer a smaller change:
import { defineConfig } from '@rstest/core';
export default defineConfig({
output: {
externals: ['react', 'lodash'],
},
});
If a previous Jest setup used moduleNameMapper to stub CSS or SCSS with identity-obj-proxy, compare that behavior explicitly instead of assuming the native Rstest path is equivalent:
import { defineConfig } from '@rstest/core';
export default defineConfig({
tools: {
rspack: (config, { rspack }) => {
config.plugins ??= [];
config.plugins.push(
new rspack.NormalModuleReplacementPlugin(
/\.(css|less|scss)$/,
'identity-obj-proxy',
),
);
},
},
});
Only keep this if the tests do not depend on real style behavior and the timing improvement is measurable.
If startup is still slow and the expensive part is unclear, use Rsdoctor to see whether time is dominated by entries, loaders, plugins, or dependency chains.
Once startup is acceptable and execution remains slow, stop tuning bundling first. Focus on the runtime path.
Investigate in this order:
--trace to see whether time is spent in setup hooks, the test body, retries, or teardown.samply for CPU time distribution--heap-prof for memory allocation--inspect for step-through debuggingCommon runtime fixes to test one by one:
beforeEach when it can be shared safely.pool.maxWorkers settings if worker oversubscription or contention is suspected.Every optimization attempt must follow this loop:
Report the result in a compact table when possible:
| Change | Cold run | Warm run | Outcome |
| -------------------------------------------- | -------- | -------- | ------- |
| Baseline | | | |
| output.bundleDependencies: false | | | |
| CSS stub via NormalModuleReplacementPlugin | | | |
Do not stack multiple “maybe faster” changes before measuring. That destroys the ability to attribute the result.
development
Opinionated Rslib recommendations for modern JS/TS npm package design covering pure ESM, strict TypeScript, explicit exports, small stable APIs, pragmatic dependencies, accurate sideEffects, correct declarations, package validation, provenance, README.md, and AGENTS.md. Use when the user wants to make a JS/TS package more modern, check whether the current package setup is healthy, review package.json/exports/types/dependencies/docs/release readiness, or apply a modern library baseline.
development
Create or update draft GitHub releases for the current project's main GitHub repository, then organize GitHub-generated release notes into user-friendly sections without rewriting release note items. Use for preparing, formatting, categorizing, creating, or updating GitHub release notes or draft releases, including optional highlights when the user asks for them.
tools
Migrate ESLint or other linters to Rslint. Use when asked to replace ESLint flat config, lint scripts, VS Code ESLint settings, inline directives, rules, presets, plugins, or lint dependencies with Rslint equivalents.
development
Use when analyzing Rspack/Webpack bundles from local `rsdoctor-data.json` and producing evidence-based optimization recommendations.