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

@d3lm/lint-preset

v1.0.1

Published

Opinionated Oxlint + ESLint preset. Oxlint handles non-type-aware rules, while ESLint layers only type-aware rules not covered by Oxlint on top.

Readme

@d3lm/lint-preset

Opinionated dual-lint preset for JavaScript and TypeScript projects.

  • Oxlint runs the bulk of the rule set, including type-aware rules (via oxlint-tsgolint)
  • ESLint layers on only the rules Oxlint can't run yet (e.g. @typescript-eslint/naming-convention, a handful of unicorn rules, and ESLint-core gaps)

Installation

pnpm add -D @d3lm/lint-preset

The preset relies on a set of peer dependencies that it does not bundle. pnpm (with auto-install-peers, the default) pulls them in for you. With npm or yarn, install them explicitly:

pnpm add -D oxlint oxlint-tsgolint eslint typescript-eslint @typescript-eslint/eslint-plugin @stylistic/eslint-plugin eslint-config-prettier eslint-plugin-prettier eslint-plugin-oxlint eslint-plugin-jsdoc eslint-plugin-unicorn

React linting is opt-in. If you enable it for ESLint, also install the optional React Hooks peer:

pnpm add -D eslint-plugin-react-hooks

Consumer Setup

oxlint.config.ts

import { defineConfig } from 'oxlint';
import { oxlintConfig } from '@d3lm/lint-preset/oxlint';

export default defineConfig({
  extends: [oxlintConfig],
});

This pulls in the full rule set. Most rules run natively in Oxlint; a few plugins that Oxlint doesn't ship natively (custom @d3lm rules, @stylistic, eslint-plugin-prettier, eslint-plugin-unicorn, eslint-plugin-jsdoc) are wired in through Oxlint's jsPlugins. Either way you can toggle individual rules off in the same config.

React rules are disabled by default. Enable them by creating the shared config with react: true:

import { defineConfig } from 'oxlint';
import { createOxlintConfig } from '@d3lm/lint-preset/oxlint';

export default defineConfig({
  extends: [createOxlintConfig({ react: true })],
});

react also accepts an object to toggle the two opt-in groups independently (both default to true when react is enabled):

createOxlintConfig({
  react: {
    fastRefresh: true, // react/only-export-components
    performance: true, // react-perf/* rules
  },
});

eslint.config.js

import { eslintConfig } from '@d3lm/lint-preset/eslint';
import { oxlintConfig } from '@d3lm/lint-preset/oxlint';

export default eslintConfig({
  oxlintConfig,
  tsconfigRootDir: import.meta.dirname,
});

React Hooks linting is also opt-in:

import { eslintConfig } from '@d3lm/lint-preset/eslint';
import { createOxlintConfig } from '@d3lm/lint-preset/oxlint';

const oxlintConfig = createOxlintConfig({ react: true });

export default eslintConfig({
  oxlintConfig,
  react: true,
  tsconfigRootDir: import.meta.dirname,
});

The factory returns a Linter.Config[] you can spread, so you can append project-specific overrides:

import { eslintConfig } from '@d3lm/lint-preset/eslint';
import { oxlintConfig } from '@d3lm/lint-preset/oxlint';

export default [
  ...eslintConfig({
    oxlintConfig,
    tsconfigRootDir: import.meta.dirname,
  }),
  {
    files: ['src/lib/**/*.ts'],
    rules: { '@typescript-eslint/no-floating-promises': 'off' },
  },
];

Overrides spread after eslintConfig(...) land after the Oxlint disabler, which is fine for turning rules off. To turn a rule back on that Oxlint owns, use extraConfigs instead (see below) so it isn't immediately disabled again — otherwise you'll get double-reporting from both linters.

package.json

{
  "scripts": {
    "lint": "oxlint && eslint",
    "lint:fix": "oxlint --fix && eslint --fix"
  }
}

Oxlint runs first (fast feedback on the majority of issues) and ESLint only reports what Oxlint didn't cover.

ESLint Config Factory Options

eslintConfig({
  /**
   * Oxlint config object that eslint-plugin-oxlint reads to decide which
   * ESLint rules to turn off. Prefer this when your Oxlint config is created
   * in TypeScript.
   */
  oxlintConfig,

  /**
   * Path to a JSON/JSONC oxlint config file that eslint-plugin-oxlint reads
   * to decide which ESLint rules to turn off. Ignored when `oxlintConfig` is
   * provided.
   *
   * @default '.oxlintrc.json'
   */
  oxlintConfigPath: './.oxlintrc.json',

  /**
   * TypeScript project-service root. Usually `import.meta.dirname`.
   */
  tsconfigRootDir: import.meta.dirname,

  /**
   * Enable the ESLint-side React Hooks config. Pass `true`, or an object
   * `{ fastRefresh?, performance? }` mirroring the Oxlint factory. Requires
   * the optional `eslint-plugin-react-hooks` peer.
   *
   * @default false
   */
  react: true,

  /**
   * Files allowed to fall back to the default inferred project when they
   * aren't covered by the main tsconfig (e.g. top-level config files).
   *
   * @default ['*.config.ts', '*.config.mts', '*.config.cts', '*.config.js']
   */
  allowDefaultProject: ['*.config.ts', '*.config.js'],

  /**
   * Extra patterns to ignore. Layered on top of the built-in defaults unless
   * you opt out via `extendDefaultIgnores: false`.
   */
  ignores: ['generated/**'],

  /**
   * Whether to extend the built-in ignores with the ones passed in `ignores`.
   *
   * @default true
   */
  extendDefaultIgnores: true,

  /**
   * Flat-config entries layered *before* the Oxlint disabler, so custom
   * rules are still subject to the "Oxlint turns off last" ordering.
   */
  extraConfigs: [],

  /**
   * Optional rule-shape overrides forwarded to the TypeScript rule set,
   * including per-selector `namingConvention` exceptions.
   */
  namingConvention: {
    variable: { exceptions: ['MyGlobal'] },
  },

  /**
   * Tune unicorn's `prevent-abbreviations`. Extends the built-in allow list
   * and replacements by default; set `inheritAllowList` / `inheritReplacements`
   * to false to replace them outright.
   */
  preventAbbreviations: {
    allowList: ['args'],
    replacements: { props: false },
  },
});

Oxlint Config Factory Options

createOxlintConfig accepts the React options shown above plus the same rule-shape overrides, scoped to the Oxlint rule set:

createOxlintConfig({
  /**
   * Toggle React rules (boolean or `{ fastRefresh?, performance? }`).
   *
   * @default false
   */
  react: true,

  /**
   * Overrides forwarded to the JS rules (e.g. `preventAbbreviations`).
   */
  jsRulesOxlint: {
    preventAbbreviations: { allowList: ['args'] },
  },

  /**
   * Overrides forwarded to the TS rules (e.g. `namingConvention`).
   */
  tsRulesOxlint: {
    namingConvention: { variable: { exceptions: ['MyGlobal'] } },
  },
});

Development

pnpm install
pnpm run build
pnpm run lint
pnpm run test

The repo dogfoods the preset via oxlint.config.ts + eslint.config.js at the root, both pointing at ./dist/* so pnpm run lint always lints against a fresh build.