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

oxlint-compat-wrapper

v1.0.0

Published

Run any ESLint plugin in OxLint. Patches context.getScope, getAncestors, getDeclaredVariables and adds eslint-disable comment support for JS plugins.

Readme

oxlint-compat-wrapper

Run any ESLint plugin in OxLint. One function, one line, zero config.

const wrap = require('oxlint-compat-wrapper');
module.exports = wrap(require('eslint-plugin-sonarjs'));

The problem

OxLint's JS plugin API is ESLint-compatible but not ESLint-identical. Three things break when you load an existing ESLint plugin:

context.getScope()              → "not a function"
context.getAncestors()          → "not a function"
context.getDeclaredVariables()  → "not a function"
eslint-disable comments         → silently ignored

These methods exist in OxLint — but on sourceCode, not context (ESLint moved them in v9). Every ESLint plugin written before 2025 uses the old API. Without this wrapper, they crash.

The eslint-disable gap is a known open bug in OxLint with no fix planned.

What this wrapper does

For every rule in the wrapped plugin:

  1. context.getScope() → proxied to sourceCode.getScope(currentNode)
  2. context.getAncestors() → proxied to sourceCode.getAncestors(currentNode)
  3. context.getDeclaredVariables() → proxied to sourceCode.getDeclaredVariables(currentNode)
  4. context.markVariableAsUsed() → proxied to sourceCode.markVariableAsUsed()
  5. context.report() → intercepted to check eslint-disable comments before reporting
  6. Frozen context → handled by copying properties to a new object (OxLint freezes the context)

eslint-disable support

Parses and honors all ESLint disable directive formats:

// eslint-disable-next-line no-console
console.log('suppressed');

console.log('suppressed'); // eslint-disable-line no-console

/* eslint-disable no-console */
console.log('suppressed');
console.log('also suppressed');
/* eslint-enable no-console */

/* eslint-disable */
// everything in this file suppressed

Supports rule-specific disabling (eslint-disable-next-line rule-a, rule-b) and blanket disabling.

Installation

npm install -D oxlint-compat-wrapper
# or
pnpm add -D oxlint-compat-wrapper

Usage

Create a thin wrapper file for any ESLint plugin you want to use in OxLint:

// my-sonarjs-compat.js
const wrap = require('oxlint-compat-wrapper');
module.exports = wrap(require('eslint-plugin-sonarjs'));

Then reference it in .oxlintrc.json:

{
  "jsPlugins": [
    { "name": "sonarjs", "specifier": "./my-sonarjs-compat.js" }
  ],
  "rules": {
    "sonarjs/cognitive-complexity": "warn",
    "sonarjs/no-duplicate-string": "warn"
  }
}

That's it. Every rule in the plugin now works in OxLint with full eslint-disable support.

Tested plugins

| ESLint Plugin | Rules | Status | |--------------|:-----:|:------:| | eslint-plugin-sonarjs | 29 | Working | | eslint-plugin-import | 10 | Working | | eslint-plugin-jsx-a11y | 5 | Working | | eslint-plugin-lodash | 1 | Working | | ESLint core rules (via Linter.getRules()) | 10 | Working | | Custom ESLint plugins | 20+ | Working |

Cherry-picking ESLint core rules

You can extract specific built-in ESLint rules that OxLint doesn't have natively:

// my-eslint-core.js
const wrap = require('oxlint-compat-wrapper');
const { Linter } = require('eslint');

const linter = new Linter();
const allRules = linter.getRules();

const picked = {};
for (const name of ['camelcase', 'no-return-await', 'prefer-arrow-callback']) {
  const rule = allRules.get(name);
  if (rule) picked[name] = rule;
}

module.exports = wrap({ rules: picked });
{
  "jsPlugins": [
    { "name": "eslint-core", "specifier": "./my-eslint-core.js" }
  ],
  "rules": {
    "eslint-core/camelcase": "warn",
    "eslint-core/no-return-await": "warn"
  }
}

How it works

OxLint's JS plugin API provides sourceCode.getScope(), sourceCode.getAncestors(), etc. — but legacy ESLint plugins expect them on context. The wrapper:

  1. Copies all properties from the frozen context to a new plain object
  2. Adds the missing methods by proxying to sourceCode
  3. Tracks the currentNode as the visitor traverses the AST — so getScope() returns the scope for the node being visited, not the root
  4. Wraps context.report() to parse and honor eslint-disable comments before forwarding

The eslint-disable parser runs once per file (when the rule is first invoked), builds a map of disabled lines/ranges, and checks each report() call against it. Overhead is ~1-2ms per file.

Why not wait for OxLint to fix this?

  • sourceCode.getScope() was added in OxLint v1.45 (Oct 2025) — but context.getScope() is not planned. OxLint considers it deprecated.
  • eslint-disable for JS plugins is an open bug (#20747) since March 2026 with no assignee, no milestone, no fix timeline.
  • Hundreds of ESLint plugins use the legacy API. Waiting means they can't be used in OxLint.

This wrapper bridges the gap today.

API

const wrap = require('oxlint-compat-wrapper');
const wrappedPlugin = wrap(eslintPlugin);

Parameters:

  • eslintPlugin — an ESLint plugin object with a rules property ({ rules: { 'rule-name': ruleObject } })

Returns:

  • A new plugin object with the same rules, wrapped for OxLint compatibility

The wrapper does not modify the original plugin.

License

MIT