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

@leaflink/eslint-config

v4.4.3

Published

Opinionated linting configuration for LeafLink's front-end repositories.

Readme

@leaflink/eslint-config

Configuration for ESLint, Prettier, Stylelint, and Commitlint at LeafLink.

version downloads MIT License semantic-release Commitizen friendly

Table of Contents

Features

Installation

[!IMPORTANT]

Requirements ESLint v9 and above Node.js v20 and above Stylelint v16 and above (optional)

If you're going to be using both eslint & stylelint in your project, then the fastest way to get started is to run:

npx install-peerdeps --dev @leaflink/eslint-config

If you don't need to leverage stylelint in your project, then just install this package along with eslint v9:

npm install --save-dev eslint@9 @leaflink/eslint-config@latest

If you want to manually install all peer dependencies without using install-peerdeps, you can run:

npm install --save-dev eslint@9 @leaflink/eslint-config@latest stylelint@16 stylelint-config-standard-scss stylelint-config-standard-vue stylelint-order postcss-html

Migration to v4 (ESLint v9+, Stylelint v16+, Node v20+)

  1. Migrate your app to Node 20 or greater.
  2. npm uninstall eslint-config-leaflink stylelint stylelint-config-standard-scss stylelint-config-standard-vue.
  3. npx install-peerdeps --dev @leaflink/eslint-config.
  4. Optionally install globals if you have custom globals set in your projects eslint file: npm install -D globals.
  5. Rename .eslintrc.js to eslint.config.mjs.
  6. Refactor file to use esm syntax & ESLint flat configs. More below on this.
  7. Delete .eslintignore and move listed files/directories into an { ignores: [...] } block inside your ESLint config.
  8. Find/replace @ts-ignore -> @ts-expect-error. Be aware, this may actually cause ts errors in the event that the @ts-ignore wasn't actually doing anything. This is a good thing, just remove the comment altogether.
  9. Change npm lint command: eslint --ext .ts,.js,.vue src -> eslint ..
  10. Rename stylelint.config.js to stylelint.config.mjs and refactor to esm. If using a json format, it should be fine to leave it as is.
  11. Rename commitlint.config.js to commitlint.config.mjs and refactor to esm. If using a json format, it should be fine to leave it as is.

[!NOTE] You may also find yourself having to address certain eslint errors that didn't appear before. All 3rd party configs and plugins were upgraded as part of this update, hence some rules have been changed.

Docs: https://eslint.org/docs/latest/use/configure/migration-guide

Summary of main changes

  • Your eslint file becomes an array of config objects instead of a single config object
  • Global ignores need to be in their own object.
  • Move all objects from overrides up a level - just "flatten" the overrides array and get rid of it.
  • env objects need to get converted to languageOptions: { globals: { ...globals.node, ...globals.jest } } and you need to load globals from the globals npm package. They aren't baked in anymore.
  • files always needs to be an array: files: '**/*.spec.ts' -> files: ['**/*.spec.ts']
  • files globs need to be a little more specific it seems. files: ['*.spec.ts'] -> files: ['**/*.spec.ts']

Example

Old usage (.eslintrc.js):

module.exports = {
  extends: 'leaflink',

  // your custom overrides
};

New usage (eslint.config.mjs):

import leaflinkConfig from '@leaflink/eslint-config';

export default [
  ...leaflinkConfig,

  // your custom overrides (using new flat config format)
];

Usage

Create an eslint.config.mjs file in the root of your project and extend from the shared LeafLink config.

[!IMPORTANT] If you haven't enabled esm in your project by default, you may need to name your config file eslint.config.mjs. Otherwise, projects that use "type": "module" in their package.json can probably use the .js extension.

import leaflinkConfig from '@leaflink/eslint-config';
import { defineConfig, globalIgnores } from 'eslint/config';

export default defineConfig([
  ...leaflinkConfig,

  globalIgnores(['my-custom-path', '**/generated/**']),

  // Optionally add overrides here
  {
    // files: ['**/*.ts', '**/*.tsx'], // (optional) only apply to specific files
    rules: {
      // your rules overrides here
    },
  },
]);

Browsers

If your test files rely on a browser environment, you probably need to configure ESLint to be aware of the browser globals since they are not included by default from Vitest or Testing Library.

// eslint.config.js
import { defineConfig } from 'eslint/config';
import globals from 'globals';

export default defineConfig([
  ...leaflinkConfig,

  {
    files: ['**/?(*.)+(spec).[jt]s'],
    languageOptions: {
      globals: {
        ...globals.browser,
      },
    },
  },
]);

Including the browser globals for test files will prevent linting errors such as 'window' is not defined and 'document' is not defined.

Be sure to install globals with npm i -D globals.

If you have any other scripts outside of a Vue or React context that rely on the browser, you can tell ESLint to provide certain globals be adding a globals comment to the top of the file.

For example, imagine that the following is for a runtime script called unregisterServiceWorker.ts.

/* global window, navigator */

export default function unregisterServiceWorker() {
  if (window && navigator?.serviceWorker) {
    navigator.serviceWorker.getRegistrations().then(function (registrations) {
      for (const registration of registrations) {
        registration.unregister();
      }
    });
  }
}

Prettier

Prettier is automatically run through eslint with LeafLink's default configuration. You can optionally add a prettier.config.mjs configuration file in the root of your project and it will take precedence over the built-in config within @leaflink/eslint-config.

If you'd like to extend our prettier config and only override a couple of properties, you can do the following:

prettier.config.mjs

import leaflinkConfig from '@leaflink/eslint-config/prettier.js';

/**
 * @see https://prettier.io/docs/en/configuration.html
 * @type {import("prettier").Config}
 */
const config = {
  ...leaflinkConfig,
  // your overrides here
};

export default config;

Stylelint

In your .stylelintrc file, you can extend from the shared LeafLink stylelint config.

{
  "extends": ["@leaflink/eslint-config/stylelint"]
}

Or you can do so in your package.json:

{
  "stylelint": {
    "extends": ["@leaflink/eslint-config/stylelint"]
  }
}

Or in stylelint.config.mjs:

export default {
  extends: ['@leaflink/eslint-config/stylelint'],
};

commitlint

Create a commitlint.config.mjs file at the root of your project with the following content:

import leaflinkConfig from '@leaflink/eslint-config/commitlint.js';

export default leaflinkConfig;

If you want to extend the leaflinkConfig with custom overrides, you can do so like this:

import leaflinkConfig from '@leaflink/eslint-config/commitlint.js';

export default Object.assign(leaflinkConfig, {
  // your overrides here
  rules: {
    'scope-case': [1],
  },
});

Lastly, in order for husky to lint your commit messages, you need to create a .husky/commit-msg file in your project with the following content:

#!/usr/bin/env sh

npx --no -- commitlint --edit $1

Husky Hooks (Enabled by Default)

Husky hooks are enabled by default and will run automatically when users commit or push. However, individual users can opt-out of Husky hooks in several ways:

Temporary opt-out (single command):

HUSKY=0 git commit -m "Your commit message"

Session opt-out:

export HUSKY=0
git commit -m "Your commit message"
git push
unset HUSKY

Global opt-out (per user): Users can create ~/.config/husky/init.sh with:

export HUSKY=0

[!Note]

It's recommended you attempt to remove as many of your specific overrides as possible and see how much can be autofixed to be inline with this shared configuration. You can extend from leaflink and set temporary overrides to turn some rules off in order to make the initial migration easier.