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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@homer0/eslint-plugin

v14.2.2

Published

My custom configurations for ESLint.

Readme

@homer0/eslint-plugin

My custom configurations for ESLint

Installation

pnpm add @homer0/eslint-plugin --save-dev
# or
npm install @homer0/eslint-plugin --save-dev

Requirements

| Package | Minimum Version and notes | | ---------- | ------------------------------------------------------------------------------------------------------------------------- | | Node | >=20.19 | | ESLint | >=9.39.1 - with flat config | | TypeScript | >=5 - with ESM |

Usage

Import the plugin in your ESLint config, and add it to the extends list:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import eslintPlugin from '@homer0/eslint-plugin';

export default defineConfig([
  files: ['src/**/*.ts'],
  extends: [
    eslintPlugin.configs.node,
    eslintPlugin.configs.esm,
  ],
]);

Or, you can create a config with your desired presets:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import { createConfig } from '@homer0/eslint-plugin/create';

export default defineConfig([
  createConfig({
    importUrl: import.meta.url, // to configure TS paths resolution
    extends: ['node-ts-with-prettier'],
  }),
]);

Configurations

Originally, all configurations were based on Airbnb's base config, with some customizations on top of it. But now, since Airbnb hasn't published a flat config version yet (as of November 2025), I added an airbnb folder inside the project and copied their rules (except for the deprecated ones), in flat config format.

The airbnb folder is temporary (I think), as I eventually plan to review all the rules and create my own base config from scratch.

So, for now, my configs are still based on Airbnb's base rules, with some customization, minus the rules that are deprecated or moved to the stylistic plugin (as I leave all my formatting to Prettier).

Now, there are three main types of configurations:

  • environment-specific: They are meant to be used as a base for your projects, like node or browser.
  • feature-specific: They are meant to be added on top of those base configs, like esm, jsdoc, and/or testing.
  • combined: To cover the most common cases, these features combine both environment and features, like node-ts, and node-ts-testing.

Environment and combined configurations include a Prettier version with the suffix -with-prettier. They add the Prettier's config that takes care of disabling all the ESLint rules that may conflict with Prettier's formatting.

| Name | Type | Description | Prettier version | | --------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | | browser | environment | For browser-based projects; it's like the one for node, but with the browser globals and without the eslint-plugin-n. | ✅ | | node | environment | For Node.js and the tooling outside browser-based projects. It uses the eslint-plugin-n's recommended config. | ✅ | | node-ts | combined | For Node.js projects using TypeScript; it extends the node config and adds TypeScript support. | ✅ | | node-ts-tests | combined | Extends node-ts and disables a few rules for acceptable scenarios in testing environments (like no-magic-numbers). | ✅ | | tests | feature | It disables a few rules for acceptable scenarios in testing environments (like no-magic-numbers). | ❌ | | esm | feature | For projects using ESM modules; it sets the sourceType to module and customizes a few rules accordingly (mostly around the eslint-plugin-import-x). Important: Don't use this config with a TypeScript based config, just leave the extensions validation to the TS compiler. | ❌ | | ts | feature | For TypeScript projects; it adds TypeScript support on top of any other config. | ❌ | | jsdoc | feature | For projects using JSDoc comments; it adds rules from the eslint-plugin-jsdoc. | ❌ |

Frameworks and libraries

Here are a few special configs and tools for specific frameworks and libraries I use.

Next.js

If you are working on a Next.js project, there's a custom export and config creator for it, but it requires you to install their config:

pnpm add eslint-config-next --save-dev
# or
npm install eslint-config-next --save-dev

Then, you can import the plugin in your config and use it like this:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import eslintPlugin from '@homer0/eslint-plugin/nextjs';

export default defineConfig([
  files: ['src/**/*.ts'],
  extends: [
    eslintPlugin.configs['nextjs-with-prettier'],
  ],
]);

Yes, it has a Prettier version too!

Or, like with the other configs, you can use a config creator:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import { createNextjsConfig } from '@homer0/eslint-plugin/nextjs/create';

export default defineConfig([
  createNextjsConfig({
    importUrl: import.meta.url, // to configure TS paths resolution
    // These are the options and their default values:
    prettier: true,
  }),
]);

React

If you are working with just React (no Next), there's also a custom export and config creator for it, and it also requires some plugins to be installed:

pnpm add eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y --save-dev
# or
npm install eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y --save-dev

But different from the Next.js config, this is not a base config, so you'd have to use it on top of another config, like node-ts or browser.

// eslint.config.js
import { defineConfig } from 'eslint/config';
import plugin from '@homer0/eslint-plugin';
import reactPlugin from '@homer0/eslint-plugin/react';

export default defineConfig([
  files: ['src/**/*.ts'],
  extends: [
    eslintPlugin.configs['node-with-prettier'],
    reactPlugin.configs.react,
    eslintPlugin.configs.esm.
  ],
]);

Or, you can use the config creator:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import { createReactConfig } from '@homer0/eslint-plugin/react/create';

export default defineConfig([
  createReactConfig({
    importUrl: import.meta.url, // to configure TS paths resolution
    baseConfig: 'node', // 'node' | 'browser', default is 'node'
    // These are the options and their default values:
    esm: true,
    jsdoc: false,
    prettier: true,
    tests: false,
    ts: true,
  }),
]);

Config creator features

When using the config creators (like createConfig or createNextjsConfig), you get a few extra features besides the TS path resolution setup.

files: Files inclusion

While this option behaves similarly to ESLint's native files option, it has some extra capabilities to make your life easier. You can set the values to:

  • A glob pattern string (like src/**/*.ts).
  • all to include all JS/TS files in your project (basically, it resolves to **/*.{js,jsx,the-rest}).
  • all-inside:<path> to include all JS/TS files inside a specific folder (like all-inside:src resolves to src/**/*.{js,jsx,the-rest}).

And you can send an array of those values too.

Custom tsconfig.json

There are two options for working with custom tsconfig.json files:

  • tsConfigName: If your tsconfig.json file has a different name (like tsconfig.app.json), you can specify it here. Default is tsconfig.json.
  • tsConfigPath: If your tsconfig.json file is not in the root folder, you can specify its path here. Default is ./ (the root folder).

Those are two different options because you normally have either a custom name on the root, like tsconfig.production.json, or a custom path, like tests/tsconfig.json.

Extraneous dependencies

The no-extraneous-dependencies rule from eslint-plugin-import-x (and previously the original eslint-plugin-import) is very useful to avoid importing packages that are not listed in your package.json dependencies... but it's always a pain to configure properly, and when you are bundling, it's very common to just disable it altogether.

So, with the config creators, you can use the extraneousDependencies option to easily configure it according to your situation. The option is an object with the following keys:

  • devFiles: An array of glob patterns for files that are considered development files that are allowed to import devDependencies. By default, it includes a big list, from the airbnb config, of all major JS/TS tools config files (like webpack.config.js, jest.config.ts, etc).
  • bundledDependencies: A list of packages paths that are bundled in your project's build process. For example, if you are bundling urijs in your build, you can add it here, and the rule will allow importing it without listing it in your dependencies.

ignoreUnresolved: Ignore unresolved imports

With the migration to ESM, and the use of custom path mappings in TypeScript, it's common to have some imports that ESLint can't resolve properly, even if they work fine at runtime or when compiled with TypeScript. To avoid having to manually override the import-x/no-unresolved, or turn it off completely, you can use the ignoreUnresolved option in the config creators, and it will automatically add those exceptions for you, while keeping the rule with the base configuration.

Ignore files

With the new flat config, .eslintignore files are not supported anymore, and you now need a workaround to load the patterns from those files into your config.

Built into the config creators is a feature that automatically loads .eslintignore and/or .gitignore patterns into your config, so you don't have to worry about it.

By default, the feature will crawl upwards from your config file location until it finds a .gitignore file and load all the patterns from all the .eslintignores it finds along the way, and the ones from the .gitignore file.

Note: It uses .eslintignores (with an s at the end) as the default ignore file name, to avoid the "deprecated" warning from ESLint when it finds a .eslintignore file.

The option is loadIgnoreFile, and it can be:

| Type | Description | | -------- | ------------------------------------------------------------------------------------------------------------------------------- | | true | Load all the .eslintignore files it finds until it sees a .gitignore, and then load that too. This is the default behavior. | | false | Disable the feature. | | number | Specify how many levels upwards it should look for ignore files. | | object | Customize the behavior with more options (see below). |

And if you use an object, here are the available options:

| Key | Type | Description | | ------------------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | limit | false \| number \| '.gitignore' | Defines the behavior for how many levels upwards it should look for ignore files. If false, it will only look in the directory of the config file. If '.gitignore', it will look until it finds a .gitignore file. Otherwise, it will look up to the specified number of levels. Default is '.gitignore'. | | includeGitignore | boolean | Whether to include patterns from the .gitignore file when (and if) found. Default is true. | | ignoreFileName | string | Optional. If you want to use a different ignore file name instead of .eslintignores, you can specify it here. |

Rules

Instead of listing the rules here, you can check all the files inside any rules directory outside airbnb (like src/rules/es6.ts or src/react/rules/style.ts) and you'll see all the customizations I made, with a comment explaining why I took that decision, and a link to the relevant documentation.

Contributing

No, thanks :)