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

uba-fast-lint-config

v1.1.0

Published

Fast ESLint + Prettier alternative using Biome, oxlint, and slim ESLint for gap plugins

Downloads

14

Readme

uba-fast-lint-config

A fast ESLint + Prettier replacement using Biome (formatter), oxlint (bulk linting), and a slim ESLint layer for gap plugins.

Drop-in replacement for uba-eslint-config with the same rule coverage and a compatible API.

How It Works

Three tools, each doing what it does best:

biome format .     →  formatting only (replaces Prettier)        ~40x faster
oxlint .           →  ~200 lint rules in Rust                    ~50-100x faster
eslint .           →  ~80 gap rules (plugins oxlint can't run)   same speed, way fewer rules

eslint-plugin-oxlint sits between oxlint and ESLint — it auto-disables any ESLint rule that oxlint already covers, so nothing runs twice.

| Layer | Tool | What it does | |-------|------|--------------| | Formatting | Biome | Replaces Prettier — formats JS/TS/JSON/CSS/HTML | | Bulk linting | oxlint | ~200 rules from eslint core, typescript-eslint, react, jsx-a11y, unicorn, promise, import, vitest | | Gap plugins | ESLint (slim) | Plugins with no oxlint equivalent: perfectionist, canonical, check-file, function-name, cypress, graphql, storybook, tanstack-query, tanstack-router, tailwindcss, chai-friendly, + gap rules from react/unicorn/import/typescript/vitest/promise that oxlint hasn't implemented | | Dedup | eslint-plugin-oxlint | Auto-disables ESLint rules oxlint already covers (must be last in config) |

Installation

pnpm add -D uba-fast-lint-config

This installs Biome, oxlint, ESLint, and all gap plugins as transitive dependencies.

Setup

1. Copy the config files

Your project needs three config files. Copy them from this package or generate them:

biome.json — copy from node_modules/uba-fast-lint-config/biome.json, or generate:

import { generateFormatterConfig } from "uba-fast-lint-config";
const { config, gaps } = generateFormatterConfig({ appType: "fullstack" });
// Write `config` to biome.json
// `gaps` lists Prettier plugins with no Biome equivalent + workarounds

.oxlintrc.json — copy from node_modules/uba-fast-lint-config/.oxlintrc.json:

cp node_modules/uba-fast-lint-config/.oxlintrc.json .

eslint.config.js — import the gap config:

// eslint.config.js
import { ubaFastLintConfig } from "uba-fast-lint-config";

export default [...ubaFastLintConfig];

2. Add scripts to package.json

{
  "scripts": {
    // --- Two-tier lint commands ---
    "lint:fast": "oxlint .",                          // ~200 rules, instant
    "lint:full": "oxlint . && eslint .",              // ~280 rules, slightly slower
    "lint:fast:fix": "oxlint --fix .",
    "lint:full:fix": "oxlint --fix . && eslint --fix .",

    // --- Formatting ---
    "format": "biome format --write .",
    "format:check": "biome format .",

    // --- All-in-one ---
    "fix": "biome format --write . && oxlint --fix . && eslint --fix .",
    "check": "biome format . && oxlint . && eslint ."
  }
}

3. (Optional) Pre-commit hook

# .husky/pre-commit
npx sort-package-json          # replaces prettier-plugin-packagejson
biome format --write .
oxlint .
eslint .
git add -u

Two Speed Tiers

The key insight: you don't always need every rule.

Fast tier: oxlint + biome only

biome format --write . && oxlint .
  • ~200 lint rules from eslint core, typescript, react, jsx-a11y, unicorn, promise, import, vitest
  • Catches the vast majority of bugs, security issues, and style violations
  • Runs in milliseconds on most codebases
  • Use this for: pre-commit hooks, watch mode, quick iteration, editor on-save

Full tier: oxlint + eslint + biome

biome format --write . && oxlint . && eslint .
  • ~280 rules — everything from the fast tier, plus ~80 gap rules from ESLint plugins
  • Adds: perfectionist sorting, import resolution/cycle detection, canonical import aliases, filename conventions, function naming, React gap rules (boolean-prop-naming, function-component-definition, etc.), unicorn gap rules (prevent-abbreviations, etc.), vitest gap rules, promise/no-return-in-finally, GraphQL, Cypress, Storybook, TanStack, Tailwind class ordering
  • Runs in seconds (ESLint is the bottleneck, but it's running ~60% fewer rules than a full ESLint setup)
  • Use this for: CI, pre-push, PR checks

Choosing which tier to use where

| Context | Recommended | Why | |---------|-------------|-----| | Editor on-save | Fast | Instant feedback, no lag | | Pre-commit hook | Fast or Full | Fast for speed; Full if you want CI parity locally | | CI pipeline | Full | Catch everything before merge | | Watch mode / TDD | Fast | Don't break flow | | Pre-push hook | Full | Last chance before CI |

Usage Patterns

Fullstack (default)

// eslint.config.js
import { ubaFastLintConfig } from "uba-fast-lint-config";

export default [...ubaFastLintConfig];

Enables: React, TypeScript, Cypress, TanStack Query/Router, Tailwind, Perfectionist, Canonical, etc.

Backend only

import { generateLintConfig } from "uba-fast-lint-config";

const { eslintConfig } = generateLintConfig({ appType: "backendOnly" });

export default eslintConfig;

Disables: React, Cypress, GraphQL, TanStack, Tailwind, Storybook.

Fine-grained control

import { generateLintConfigByFeatures } from "uba-fast-lint-config";

const { eslintConfig } = generateLintConfigByFeatures({
  appType: "fullstack",
  shouldEnableTypescript: true,
  shouldEnableReact: true,
  shouldEnableCypress: false,
  shouldEnableGraphql: true,
  shouldEnableStorybook: false,
  shouldEnableQuery: true,
  shouldEnableRouter: false,
  shouldEnableTailwind: true,
});

export default eslintConfig;

Storybook (opt-in)

Storybook requires optional peer deps:

pnpm add -D eslint-plugin-storybook storybook
const { eslintConfig } = generateLintConfig({
  appType: "fullstack",
  shouldEnableStorybook: true,
});

CI Pipeline Example

# .github/workflows/ci.yml
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22, cache: pnpm }
      - run: pnpm install --frozen-lockfile

      # Fast tier — fails fast on obvious issues
      - run: biome format .
      - run: oxlint .

      # Full tier — catches everything
      - run: eslint .
        env:
          CI: "true"  # enables import/no-cycle (expensive, CI-only)

Exports

| Export | Description | |--------|-------------| | ubaFastLintConfig | Default fullstack ESLint gap config array (spread into eslint.config.js) | | generateLintConfig({ appType, shouldEnableStorybook, shouldEnableTypescript }) | Returns { eslintConfig, oxlintConfig, biomeFormatterConfig } | | generateLintConfigByFeatures({ ... }) | Same bundle with per-feature flags | | generateFormatterConfig({ appType }) | Returns { config, gaps } for Biome formatter | | getScripts() | Returns recommended package.json scripts |

Migrating from uba-eslint-config

See docs/MIGRATION_GUIDE.md for step-by-step instructions.

Known Gaps

See docs/KNOWN_GAPS.md for the full list. Summary:

  • 27 type-aware TS rules (await-thenable, no-floating-promises, etc.) — waiting on oxlint to stabilize --type-aware flag
  • ~8 low-risk rules — engine-checked, empty config, or formatter-handled
  • Prettier plugin gapsprettier-plugin-packagejson (workaround: sort-package-json), prettier-plugin-tailwindcss (workaround: eslint-plugin-tailwindcss), embedded language formatting (no workaround)

License

MIT