A lightweight, composable ESLint plugin for TypeScript and React projects
Zero-config presets with all the rules from eslint-config-kubit, now as a proper ESLint plugin.
Compatible with OxLint and ESLint flat config.
Installation | Quick Start | Configs | Rules | Migration | Contributing
@kubit-ui-web/eslint-plugin-kubit replaces eslint-config-kubit with a better architecture:
eslint-config-kubit (old) |
@kubit-ui-web/eslint-plugin-kubit (new) |
|---|---|
| Opaque function that hides everything | Transparent, composable flat configs |
| ~15 plugins bundled as dependencies | All plugins bundled — one install, zero setup |
| Incompatible with OxLint | Use only what OxLint doesn't cover |
isReact flag controls rule loading |
Pick recommended or recommended-react |
| Must override to disable rules | Cherry-pick configs: base, typescript, react |
- Node.js: >= 20.19.0
- ESLint: >= 9.0.0
All ESLint plugins come bundled — one install, zero extra setup:
# Using pnpm (recommended)
pnpm add -D eslint @kubit-ui-web/eslint-plugin-kubit
# Using npm
npm install --save-dev eslint @kubit-ui-web/eslint-plugin-kubitThat's it. All plugins (TypeScript, React, a11y, Prettier, Perfectionist, Jest, etc.) are included as direct dependencies and installed automatically.
// eslint.config.js
const eslint = require("@eslint/js");
const tseslint = require("typescript-eslint");
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [
eslint.configs.recommended,
...tseslint.configs.recommended,
kubit.configs.recommended,
];// eslint.config.js
const eslint = require("@eslint/js");
const tseslint = require("typescript-eslint");
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [
eslint.configs.recommended,
...tseslint.configs.recommended,
kubit.configs["recommended-react"],
];For projects using OxLint for standard rules:
// eslint.config.js
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [kubit.configs["kubit-rules"]];| Config | Description | Use case |
|---|---|---|
recommended |
All rules without React | ESLint only |
recommended-react |
All rules with React + a11y | ESLint only |
oxlint |
Only rules OxLint doesn't cover | ESLint + OxLint |
kubit-rules |
Only 2 Kubit custom rules | OxLint with minimal ESLint |
base |
General JS/ES6 rules | Cherry-pick |
typescript |
TypeScript-specific rules | Cherry-pick |
react |
React + a11y rules | Cherry-pick |
compat |
Browser compatibility | Optional |
You can mix and match individual configs:
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [
// Only TypeScript + kubit custom rules (no base JS rules)
kubit.configs.typescript,
kubit.configs["kubit-rules"],
];All rules are visible and overridable:
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [
kubit.configs.recommended,
{
rules: {
// Override any rule from the preset
complexity: ["warn", { max: 10 }],
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off",
// Configure kubit rules with your aliases
"kubit/no-index-import": [
"error",
{
aliases: {
"@/components": "./src/components/*",
"@/utils": "./src/utils/*",
},
},
],
},
},
];| Rule | Description | Auto-fix |
|---|---|---|
kubit/no-index-import |
Disallow imports from index/barrel files | ✅ |
kubit/no-relative-import-paths |
Enforce absolute import paths | ✅ |
kubit/enforce-named-exports |
Disallow default exports for better tree-shaking | - |
| Rule | Description | Auto-fix |
|---|---|---|
kubit/jsx-pascal-case |
Enforce PascalCase for JSX components | - |
kubit/no-multi-comp |
One component per file | - |
kubit/jsx-sort-props |
Enforce sorted JSX props | ✅ |
kubit/no-inline-styles |
Disallow inline style={{}} in JSX |
- |
| Rule | Description | Auto-fix |
|---|---|---|
kubit/no-public-field-interface |
Enforce behavior-only interfaces (methods, not fields) | - |
kubit/no-framework-in-core |
Prohibit framework imports inside /core/ |
- |
kubit/no-cross-boundary-import |
Enforce architectural layer boundaries | - |
All 10 kubit rules work natively in OxLint via the jsPlugins feature.
// eslint.config.js
const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
module.exports = [kubit.configs.oxlint];Use the ready-made .oxlintrc.json presets from the oxlint/ directory.
Each preset already includes jsPlugins with a relative path, so the kubit plugin loads automatically:
Or pick individual configs:
// .oxlintrc.json
{
"extends": [
"./node_modules/@kubit-ui-web/eslint-plugin-kubit/oxlint/base.json",
"./node_modules/@kubit-ui-web/eslint-plugin-kubit/oxlint/typescript.json",
"./node_modules/@kubit-ui-web/eslint-plugin-kubit/oxlint/architecture.json",
],
}Add the plugin directly to your .oxlintrc.json:
// .oxlintrc.json
{
"jsPlugins": [
{
"name": "kubit",
"specifier": "./node_modules/@kubit-ui-web/eslint-plugin-kubit/lib/index.js",
},
],
"rules": {
"kubit/no-index-import": "error",
"kubit/enforce-named-exports": "error",
"kubit/no-framework-in-core": "error",
"kubit/no-cross-boundary-import": "error",
"kubit/jsx-pascal-case": "error",
"kubit/no-multi-comp": "error",
"kubit/jsx-sort-props": [
"error",
{ "callbacksLast": true, "shorthandFirst": true, "reservedFirst": true },
],
"kubit/no-inline-styles": "error",
"kubit/no-public-field-interface": "error",
},
}| Preset | Contents |
|---|---|
oxlint/recommended.json |
Everything below combined |
oxlint/base.json |
JS quality + import/jest + kubit import rules |
oxlint/typescript.json |
TS rules + no-public-field-interface |
oxlint/react.json |
React + a11y + JSX kubit rules |
oxlint/architecture.json |
Layer boundaries + framework isolation |
| Rule category | recommended |
oxlint |
kubit-rules |
|---|---|---|---|
| Kubit custom rules | 10 | 10 | 2 |
| Prettier formatting | 1 | 1 | - |
| JS code quality | ~25 | - | - |
| Import rules | 3 | - | - |
| Perfectionist | 3 | 3 | - |
| Jest | 2 | - | - |
| TypeScript | 11 | 3 | - |
| React + a11y | ~60 | - | - |
| Total rules | ~60+ | ~20 | 2 |
See the full Migration Guide for step-by-step instructions.
TL;DR:
- const eslintFlatConfig = require("eslint-config-kubit");
- module.exports = eslintFlatConfig({ isReact: false, tsConfigPath: "..." });
+ const kubit = require("@kubit-ui-web/eslint-plugin-kubit");
+ module.exports = [kubit.configs.recommended];pnpm install
pnpm test
pnpm test:watch
pnpm test:coverage
pnpm lintWe welcome contributions! See CONTRIBUTING.md for guidelines.
This project uses Changesets for automatic version management and publishing.
Apache License 2.0 - see LICENSE for details.
Made with care by the Kubit Team