npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-remote-tester

v4.0.4

Published

Tool for running ESLint on multiple repositories

Readme

eslint-remote-tester

version

Installation | Configuration | How and when to use | Github CI Actions | Examples

eslint-remote-tester is a CLI tool for testing given ESlint rules against multiple repositories at once. It's designed to be used when validating regression of new rules. It can be used to spot whether a new rule flags false positives or crashes ESLint completely. CIs can be configured to verify regression of large set of rules so that possible null pointers or any unexpected errors are caught immediately.

Installation

# In your project directory
$ npm install --save-dev eslint-remote-tester

# eslint@>=9 is also required as peer dependency
$ npm install --save-dev eslint

The underlying git integration is done via simple-git. It requires git to be installed and that it can be called using the command git.

Configuration

Linking your local eslint plugin as a dependency

In order for eslint-remote-tester's eslint to know where the definitions for the new rules or modified existing rules are, your local eslint plugin folder needs to be symlinked. In your plugin folder, dependending on which package manager you use, run:

# Using npm package manager
npm link
npm link [your-plugin-name]

package.json

Add new script to your package.json file.

"scripts": {
    "lint:remote": "eslint-remote-tester",

eslint-remote-tester.config.js

Create new configuration file eslint-remote-tester.config.js in the root of your project. This is used as configuration file by default. Use -c or --config argument for custom configuration file, e.g. --config path/custom.config.js.

import js from '@eslint/js';

/** @type {import('eslint-remote-tester').Config} */
const config = {
    repositories: ['mui-org/material-ui', 'reach/reach-ui'],
    extensions: ['js', 'jsx', 'ts', 'tsx'],
    eslintConfig: [js.configs.recommended],
    pathIgnorePattern: `(${[
        'node_modules',
        '\\/\\.', // Any file or directory starting with dot, e.g. ".git"
        'test-results',
        'docs',
    ].join('|')})`,
};

export default config;

Configuration file can also be written in TypeScript if jiti or importx is installed. Use --config argument for TypeScript configuration file, e.g. --config eslint-remote-tester.config.ts.

import type { Config } from 'eslint-remote-tester';
import js from '@eslint/js';

const config: Config = {
    repositories: ['mui-org/material-ui', 'reach/reach-ui'],
    extensions: ['js', 'jsx', 'ts', 'tsx'],
    eslintConfig: [js.configs.recommended],
};

export default config;

Configuration options

| Name | Description                               | Type | Required | Default | Example | | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | :----------------- | :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | | repositories | Repositories to scan in format of owner/project. See eslint-remote-tester-repositories for shared list of repositories. | string[] | :white_check_mark: | :x: | ['mui-org/material-ui', 'reach/reach-ui'] | | extensions | Extensions of files under scanning | string[] | :white_check_mark: | :x: | ['js', 'jsx', 'ts', 'tsx'] | | eslintConfig | ESLint configuration. Supports lazy initialization based on currently tested repository when a function is passed. Function is called with current repository and its location on filesystem. | object \| ({ location, repository }) => object See Configuring ESLint | :white_check_mark: | :x: | [js.configs.recommended] (options) => options.repository === 'my-repo' ? [js.configs.recommended] : [] | | pathIgnorePattern | Regexp pattern string used to exclude paths | string | :x: | :x: | (node_modules\|docs\|\\/\\.git) | | maxFileSizeBytes | Max file size used to exclude bigger files | number | :x: | 2000000 | 1500000 | | rulesUnderTesting | Array of rules or a filter method used to filter out results. Use undefined or empty array when ESLint crashes are the only interest. Filter method is called with ruleId and options. | string[] \| (ruleId, { repository }) => boolean | :x: | [] | ['no-empty', 'react/sort-prop-types'] (ruleId, options) => ruleId === 'no-undef' && options.repository === 'owner/repo' | | resultParser | Syntax for the result parser | plaintext\|markdown | :x: | markdown on CLI. plaintext on CI | markdown | | concurrentTasks | Maximum amount of tasks run concurrently | number | :x: | 5 | 3 | | CI | Flag used to set CI mode. process.env.CI is used when not set. | boolean | :x: | value of process.env.CI === 'true' | true | | logLevel | Filter log messages based on their priority | verbose\|info\|warn\|error | :x: | verbose | warn | | slowLintTimeLimit | Time limit before linting of a single file is considered as slow, and logged as warning. Disabled by default. | number\|null | :x: | :x: | 5 // 5 seconds | | cache | Flag used to enable caching of cloned repositories. For CIs it's ideal to disable caching due to limited disk space. | boolean | :x: | true | true | | timeLimit | Time limit before scan is interrupted and exited successfully. Ideal for avoiding CI timeouts in regression tests. | number | :x: | 5.5 * 60 * 60, // 5 hours 30 minutes | 5 * 60 * 60 // 5 hours | | compare | Flag used to enable result comparison mode. Compares results of two scans and output the diff. Ideal for identifying new false positives when fixing existing rules. See Fixing existing rules. | boolean | :x: | false | true | | updateComparisonReference | Flag used to enable result comparison reference updating. Indicates whether comparison base should be updated after scan has finished. Ideal to be turned off once initial comparison base has been collected. | boolean | :x: | true | true | | onComplete | Callback invoked once scan is completed. Asynchronous functions are supported. Ideal for extending the process with custom features. | (results, comparisonResults, repositoryCount) => void|Promise<void>. See onComplete example. | :x: | :x: | async (results, comparisonResults, repositoryCount) => {} |

Execution

Run npm run lint:remote. Results are written into ./eslint-remote-tester-results folder.

How and when to use

Disclaimer: This section is still work in progress.

Developing new ESLint rules

When developing new ESLint rules you'll be most interested in results reported by the rule. As the AST of Javascript and Typescript can cause very unexpected results it is not enough to test the rule only against unit tests and a small amount of repositories. Testing the rule against 1000's of repositories can reveal unexpected results:

  • Does the rule report the intended patterns?
  • Does the rule falsely mark valid patterns as errors?
  • Are the error messages set as expected?

Follow these steps to test the new rule easily:

  1. Include new rule in rulesUnderTesting
  2. Configure eslintConfig with the new rule and its options
  3. Run eslint-remote-tester locally
  4. Check generated results at ./eslint-remote-tester-results

Fixing existing rules

Fixing existing rules without breaking old functionality or introducing new bugs can be difficult. By testing the rule against 1000's of repositories and comparing these reports against previous build's reports it is easily seen whether anything broke.

Running eslint-remote-tester in comparison mode allows developers to see the exact changes in ESLint reports their code changes introduced. Example of comparison results can be found at Examples section.

Follow these steps to test code changes of existing rules easily:

  1. Include given rule in rulesUnderTesting
  2. Configure eslintConfig with the rule and its options
  3. Stash code changes of the fix so that the current setup matches the latest build (typically master branch)
  4. Enable compare in the configuration file. This will generate comparison reference results.
  5. Run eslint-remote-tester locally
  6. Apply code changes of the fix back
  7. Disable updateComparisonReference in the configuration file. This will disable comparison reference updates - meaning that all next comparison runs are compared against the previously generated results (e.g. master branch).
  8. Run eslint-remote-tester locally again
  9. Check generated results at ./eslint-remote-tester-results/comparison-results. New reports introduced by these code changes are saved in added.md. Reports not seen with latest changes are saved in removed.md.
  10. Repeat steps 8-9 and keep fixing the rule until added.md does not contain new false positives and removed.md does not contain unintended reports.

Plugin maintainer making sure new PRs don't introduce new false positives

Reviewing PRs of ESLint plugin projects can be slow if maintainers are expected to test every change manually. Plugin projects can set their CI to run eslint-remote-tester on comparison mode for each new PR. The CI will compare ESLint reports between the master and PR branches, and report all new and removed reports. This way the reviewers can easily see whether PR actually fixed the issue and if it introduced new bugs.

Projects using GitHub CIs can utilize eslint-remote-tester-compare-action for setting up PR comparisons.

Plugin maintainer making sure all existing rules do not crash

Plugin projects can use eslint-remote-tester for smoke testing. All the rules of given project can be run against 1000's of repositories so that only crashing rules are detected. The job can even be configured to run for a limited time so that it will test as many repositories as it can in a specific time. This can be done by setting timeLimit configuration. For Github CI the maximum time limit can be as long as 6 hours.

This project is set to run 6 hour long weekly scheduled tests using some of the most well-known ESLint community plugins. Typically the fastest plugins can test more than 10K repositories in the 6 hour time limit.

Projects using GitHub CIs can utilize eslint-remote-tester-run-action for setting up smoke tests.

Configuration maintainer making sure all repositories follow the rules

Configuration maintainers (eslint-config-*) can check all their repositories follow rules of the configuration. By using an all-inclusive filter in rulesUnderTesting all ESLint reports are picked, e.g. rulesUnderTesting: () => true.

The arguments of filter callback can be used to exclude specific rules from specific repositories:

rulesUnderTesting: function ruleFilter(ruleId, options) {
    if (ruleId === 'node/no-process-env' && options.repository === 'username/my-cli-package') {
        // my-cli-package is allowed to use process.env
        return false;
    }

    // All other rules & repositories
    return true;
}

Github CI Actions

Examples

Results:

Comparison results:

Configuration

Repositories

For easiest setup eslint-remote-tester-repositories npm package is provided. See documentation.

Target repositories can easily be found using libraries.io. They provide an API for querying repositories which depend on certain project. Example usage at repository-query-script.