Files
oxc-project__oxc/npm/oxlint-plugins/README.md
overlookmotel 9fd3bd6605 feat(linter/plugins): add @oxlint/plugins NPM package (#18824)
Alternative to #18796. Part of #18610.

## Overview

Add `@oxlint/plugins` package.

`@oxlint/plugins` package has no dependency on `oxlint`, which solves the problem raised in https://github.com/oxc-project/oxc/pull/18796#discussion_r2751286894, and is also what we wanted in the end anyway. We don't actually want plugins packages to have to depend on `oxlint`.

## Differences from other Oxc packages

This package is different from all our other packages, in that it's intended to work not only with Oxlint's ecosystem, but also with ESLint's ecosystem.

`@oxlint/plugins` will be a *runtime* dependency of plugin packages that the community create, and they may want their plugin to be compatible with both Oxlint and ESLint - this package provides the `eslintCompatPlugin` function for exactly this purpose.

Our aim is to allow plugin authors to migrate from ESLint's `create` API to Oxlint's `createOnce` API with minimum friction, and without breaking changes for their users:

1. Their plugin should remain compatible with ESLint.
2. They do not need to alter the versions of NodeJS they support (no change to `engines` field in `package.json`).
3. They can continue to publish their plugin as a CommonJS package, if that's the format they currently use.

## Package composition

Due to these requirements, the make-up of `@oxlint/plugins` is different from our other packages:

### Dual Format

This package is in "dual package" format, with both ESM and CommonJS entry points.

### Older NodeJS versions support

This package supports NodeJS versions back to v12.22.0.

https://github.com/oxc-project/oxc/blob/9938dc476f8533b7011af03cdbac328b0d00d344/npm/oxlint-plugins/package.json#L40-L42

This matches `engines` field in all ESLint 8.x.x releases:

* 8.0.0: https://www.npmjs.com/package/eslint/v/8.0.0?activeTab=code
* 8.57.1: https://www.npmjs.com/package/eslint/v/8.57.1?activeTab=code

Therefore, `@oxlint/plugins` can be used by any plugin which supports ESLint 8 or later.

Note: Download counts for ESLint 8 are still roughly equal to ESLint 9, even though v9 was released 2 years ago.

#### Notes

* Changing `target` in TSDown to `"node12"` does not result in any changes to built files. See 3rd commit in this PR.
* `exports` field in `package.json` is supported (without experimental flag) from NodeJS v12.17.0 + v14.0.0.
* `.cjs` file extension supported from NodeJS v12.0.0.

## Building the package

This PR adds 2 extra builds to TSDown config, which generate the files for the package. `build.ts` script moves the files into `npm/oxlint-plugins` directory.

Later on, we'll move the logic for moving the files into the CI release workflow, so we don't need to check the generated build files into Git.

## `@oxlint/plugins-dev`

In #18610 we decided to also add an `@oxlint/plugins-dev` to contain `RuleTester`, so we can move that out of `oxlint` package. This PR *does not* add that package. I've skipped that for now as (a) it's trickier and (b) it's much less important.
2026-02-03 15:46:17 +00:00

2.0 KiB

@oxlint/plugins

Plugin utilities for Oxlint.

This package provides optional functions to assist in creating Oxlint JS plugins and rules.

Installation

npm install @oxlint/plugins

Usage

Define functions

Use definePlugin and defineRule if authoring your plugin in TypeScript for type safety.

import { definePlugin, defineRule } from "@oxlint/plugins";

const rule = defineRule({
  create(context) {
    return {
      Program(node) {
        // Rule logic here
      },
    };
  },
});

export default definePlugin({
  meta: { name: "oxlint-plugin-amazing" },
  rules: { amazing: rule },
});

Types

This package also includes types for plugins and rules.

import type { Context, Rule, ESTree } from "@oxlint/plugins";

const rule: Rule = {
  create(context: Context) {
    return {
      Program(node: ESTree.Program) {
        // Rule logic here
      },
    };
  },
};

ESLint compatibility

If your plugin uses Oxlint's alternative createOnce API, use eslintCompatPlugin to convert the plugin so it will also work with ESLint.

import { eslintCompatPlugin } from "@oxlint/plugins";

const rule = {
  createOnce(context) {
    return {
      Program(node) {
        // Rule logic here
      },
    };
  },
};

export default eslintCompatPlugin({
  meta: { name: "oxlint-plugin-amazing" },
  rules: { amazing: rule },
});

Node.js version

This package requires Node.js 12.22.0+, 14.17.0+, 16.0.0+, or later. This matches the minimum Node.js version required by ESLint 8.

This package provides both ESM and CommonJS entry points.

So a plugin which depends on @oxlint/plugins can be:

  • Used with any version of Oxlint.
  • Used with ESLint 8+.
  • Published as either ESM or CommonJS.

Docs

For full documentation, see Oxlint JS Plugins docs.