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

@infra-x/code-quality

v0.6.2

Published

Shared Oxlint + Oxfmt presets for infra-x projects. Lint and format, one install.

Readme

@infra-x/code-quality

Shared Oxlint + Oxfmt presets for infra-x projects. One install, lint and format ready.

Install

pnpm add -D @infra-x/code-quality

[!TIP] Works with pnpm strict mode out of the box — jsPlugin paths are resolved internally via require.resolve(), no hoisting hacks needed.

Lint (Oxlint)

Create oxlint.config.ts:

import { base, unicorn, depend, react, vitest } from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [base(), unicorn(), depend(), react(), vitest()],
})

Every preset is a function. Call without arguments for defaults, or pass overrides:

export default defineConfig({
  extends: [
    base({ rules: { 'no-console': 'off' } }),
    unicorn({ rules: { 'unicorn/no-array-for-each': 'off' } }),
    vitest({ files: ['**/*.e2e-spec.ts', '**/*.spec.ts'] }),
  ],
})

[!IMPORTANT] Overrides use deep merge via defurules, plugins, settings etc. are merged (user values take priority). But files is replaced entirely — if you pass files, it overrides the preset default, not appends to it.

Available presets

Core

| Preset | Description | | ------------- | ------------------------------------------------------------------- | | base() | TypeScript, Import, categories, env, ignores. Always include first. | | typeAware() | 59 type-aware rules via tsgolint (requires TS 7.0+ tsconfig compat) | | unicorn() | 100+ code quality rules | | depend() | Flag packages replaceable with native APIs or micro-utilities |

Node.js

| Preset | Description | | ----------- | --------------------------------- | | node() | Node.js specific rules | | promise() | Promise best practices (16 rules) |

Frameworks

| Preset | Description | | ------------- | ---------------------------------------------- | | react() | React + React Hooks | | reactVite() | React + React Hooks + React Refresh (for Vite) | | nextjs() | Next.js rules + Core Web Vitals |

Backend / ORM

| Preset | Description | | ----------- | ---------------------------------------------------------------------- | | nestjs() | NestJS DI validation, Swagger consistency, decorator checks (19 rules) | | drizzle() | Drizzle ORM — enforce where clause on delete/update |

Quality

| Preset | Description | | --------- | ------------------------ | | a11y() | JSX accessibility (WCAG) | | jsdoc() | JSDoc validation |

Testing

| Preset | Description | | ------------- | ---------------------------------------- | | vitest() | Vitest best practices, environment-aware | | storybook() | Storybook best practices |

Full example

import {
  base,
  unicorn,
  depend,
  node,
  promise,
  nestjs,
  drizzle,
  vitest,
  tailwind,
} from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [
    base(),
    unicorn(),
    depend(),
    node(),
    promise(),
    nestjs(),
    drizzle({
      rules: { 'drizzle/enforce-delete-with-where': ['error', { drizzleObjectName: 'db' }] },
    }),
    vitest({ files: ['**/*.spec.ts', '**/*.e2e-spec.ts'] }),
    tailwind({ entryPoint: 'src/styles/globals.css', rootFontSize: 16 }),
  ],
})

[!NOTE] Architectural boundary checks are intentionally not part of this package. For path-based import bans use the native no-restricted-imports rule; for cycle detection use import/no-cycle; for layer/feature isolation, traversal reachability, or orphan detection run dependency-cruiser in pre-commit or CI instead of inside lint.

[!WARNING] NestJS projects must disable typescript/consistent-type-imports — NestJS DI uses runtime class references in constructor params, and without type-aware linting this rule incorrectly converts them to import type, breaking DI at runtime.

export default defineConfig({
  extends: [base(), nestjs()],
  overrides: [
    {
      files: ['**/*.{ts,mts,cts,tsx}'],
      rules: {
        'typescript/consistent-type-imports': 'off',
        'typescript/no-extraneous-class': ['error', { allowWithDecorator: true }],
      },
    },
  ],
})

Type-aware linting

The typeAware() preset enables two options on oxlint:

  • typeAware — turns on ~59 lint rules that need type information, implemented via oxlint-tsgolint (e.g. no-floating-promises, no-misused-promises, consistent-type-imports)
  • typeCheck — pipes the TypeScript compiler's own diagnostics (TS2322, TS6133, TS2307, ...) through oxlint, so oxlint reports type errors alongside lint violations
import { base, typeAware, unicorn } from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [base(), typeAware(), unicorn()],
})

[!IMPORTANT] typeAware and typeCheck are root-config-only options. Oxlint will report an error if either is set in a nested (per-package) config file. Always place typeAware() in the root config only.

Each package's own tsconfig.json is auto-detected by oxlint — no extra configuration needed. See type-aware linting for details.

Do I still need a separate tsc --noEmit step?

Short answer: yes, keep it. With typeCheck enabled, oxlint already surfaces tsc diagnostics for the files it lints, so during local development you'll usually catch type errors from lint alone. But a dedicated typecheck script is still worth keeping because:

  • Different file scope. tsc --noEmit honors the tsconfig's include / exclude. oxlint walks the filesystem by its own rules and honors ignorePatterns. The two sets overlap but are not identical — a file covered by tsconfig but excluded from lint (or vice versa) will only be checked by one of them.
  • Project-level diagnostics. tsc catches errors that aren't attached to a single source file: tsconfig.json misconfiguration (TS5xxx), broken project references, paths alias typos. Per-file type-aware linting can't see these.
  • Clearer CI failures. Running typecheck and lint as separate steps makes it obvious whether a red build is a type error or a lint rule violation.

Monorepo (nested configs)

Oxlint supports nested configuration for monorepos. Each package can have its own oxlint.config.ts that extends the root config and adds package-specific presets.

How it works

For each file being linted, oxlint uses the nearest config file relative to that file. Configs are not automatically merged — a package config must explicitly extends the root to inherit shared rules.

my-monorepo/
├── oxlint.config.ts          # root config (shared baseline + typeAware)
├── packages/
│   ├── web/
│   │   ├── oxlint.config.ts  # extends root, adds react + nextjs
│   │   └── src/
│   ├── api/
│   │   ├── oxlint.config.ts  # extends root, adds nestjs + drizzle
│   │   └── src/
│   └── shared/               # no config — inherits root directly
│       └── src/

Root config

Keep shared baseline and typeAware() at the root:

// oxlint.config.ts (root)
import { base, typeAware, unicorn, depend } from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [base(), typeAware(), unicorn(), depend()],
})

Package configs

Each package extends the root and adds its own presets. Only rules, plugins, and overrides are inherited via extendsoptions (including typeAware) are not inherited, which is the correct behavior.

// packages/web/oxlint.config.ts
import rootConfig from '../../oxlint.config.ts'
import { react, nextjs, vitest, tailwind } from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [rootConfig, react(), nextjs(), vitest(), tailwind()],
})
// packages/api/oxlint.config.ts
import rootConfig from '../../oxlint.config.ts'
import { node, nestjs, drizzle, vitest } from '@infra-x/code-quality/lint'
import { defineConfig } from 'oxlint'

export default defineConfig({
  extends: [rootConfig, node(), nestjs(), drizzle(), vitest()],
})

[!WARNING] Passing -c or --config explicitly on the CLI disables nested config lookup. Let oxlint auto-detect configs by running without -c.

[!TIP] Packages without their own oxlint.config.ts automatically use the root config — no setup needed for packages that only need the shared baseline.

Format (Oxfmt)

Create oxfmt.config.ts:

import { format } from '@infra-x/code-quality/format'
import { defineConfig } from 'oxfmt'

export default defineConfig({ ...format() })

Defaults

| Option | Value | | -------------------- | --------------------- | | semi | false | | singleQuote | true | | trailingComma | all | | printWidth | 100 | | tabWidth | 2 | | Import sorting | Grouped with newlines | | Package.json sorting | Enabled |

Override

export default defineConfig({
  ...format({ printWidth: 120, semi: true }),
})

Tailwind class sorting

import { format, tailwindFormat } from '@infra-x/code-quality/format'

export default defineConfig({
  ...format(),
  ...tailwindFormat({ stylesheet: 'src/styles/globals.css' }),
})

Scripts

{
  "scripts": {
    "lint": "oxlint",
    "lint:fix": "oxlint --fix",
    "format": "oxfmt --write .",
    "format:check": "oxfmt --check ."
  }
}

License

MIT