Skip to content

Repository files navigation

@ver0/oxlint-config

NPM Version NPM Downloads Dependents (via libraries.io), scoped npm package GitHub Actions Workflow Status


🦀 A modular Oxlint configuration used across all ver0 projects

✨ What's Included

A collection of modular Oxlint configs — the @ver0/eslint-config counterpart for the VoidZero stack (Vite+, Oxc). Import only what you need and compose via extends.

  • JavaScript — base rules plus unicorn, import, promise and oxc plugins
  • TypeScript — TypeScript rules with type-aware linting
  • React — React and hooks rules
  • Node.js — Node globals and node plugin rules
  • Browser — browser globals and restricted globals
  • Vitest — test file rules

Every rule is implemented natively in Rust inside the oxlint binary — configs need no plugin dependencies at all.

Rule philosophy

Configs are category-driven: the correctness, suspicious, pedantic and perf categories are enabled wholesale, so new oxlint rules in those categories roll in automatically with linter updates. The style and restriction categories are deliberately not enabled — style contains mutually contradictory rules (no-ternary vs prefer-ternary) and vocabulary policing; instead, a curated set of style and restriction rules is enabled explicitly. Org-wide opinions are pinned as explicit off entries so they hold even if a consumer enables more categories.

🚀 Installation

vp add -D @ver0/oxlint-config

Under Vite+ that is all — vp lint ships the linter. Standalone usage additionally requires the oxlint package:

npm install -D oxlint @ver0/oxlint-config

📖 Usage

Compose the configs you need in oxlint.config.ts via extends:

// oxlint.config.ts
import {defineConfig} from 'oxlint';
import javascript from '@ver0/oxlint-config/javascript.js';
import typescript from '@ver0/oxlint-config/typescript.js';
import node from '@ver0/oxlint-config/node.js';
import vitest from '@ver0/oxlint-config/vitest.js';

export default defineConfig({
	extends: [javascript, typescript, node, vitest],
});

In Vite+ projects the same objects go into the lint block of vite.config.ts:

// vite.config.ts
import {defineConfig} from 'vite-plus';
import javascript from '@ver0/oxlint-config/javascript.js';
import node from '@ver0/oxlint-config/node.js';

export default defineConfig({
	lint: {
		extends: [javascript, node],
	},
});

Note: shared configs require the TS config format — .oxlintrc.json cannot resolve npm packages in extends.

📦 Available Configs

Each config is a standalone module; oxlint lints JS and TS uniformly, so modules apply to all lintable files (only the vitest module scopes itself to test files). Import to enable, skip to disable — no options, no per-config dependencies.

  • JavaScript (javascript.js) — base rules: ESLint core plus unicorn, import, promise and oxc rules. Always include this one — other configs build on top of it.

  • TypeScript (typescript.js) — typescript plugin rules with type-aware linting — see Type-aware linting. Also exports typescriptUnsafe to disable strict no-unsafe-* type-safety rules:

    import typescript, {typescriptUnsafe} from '@ver0/oxlint-config/typescript.js';
    
    export default defineConfig({
    	extends: [typescript, typescriptUnsafe],
    });
  • React (react.js) — React and hooks rules. Stylistic JSX rules are intentionally absent — that is oxfmt's job.

  • Node.js (node.js) — Node.js environment and globals (ESM flavor — CJS globals like require and __dirname are disallowed) plus node plugin rules.

  • Browser (browser.js) — browser environment and globals, restricts confusing globals like event, name, location shadowing.

  • Vitest (vitest.js) — rules for test and benchmark files (*.test.*, *.benchmark.*).

Type-aware linting

typescript.js turns on typeAware and includes rules that need type information. They require oxlint-tsgolint:

vp add -D oxlint-tsgolint

Not ready for type-aware linting? Disable it in the consuming config:

export default defineConfig({
	extends: [javascript, typescript],
	options: {typeAware: false},
});

🌟 Common Configurations

Node.js API project:

// oxlint.config.ts
import {defineConfig} from 'oxlint';
import javascript from '@ver0/oxlint-config/javascript.js';
import typescript from '@ver0/oxlint-config/typescript.js';
import node from '@ver0/oxlint-config/node.js';
import vitest from '@ver0/oxlint-config/vitest.js';

export default defineConfig({
	extends: [javascript, typescript, node, vitest],
});

React web application:

// oxlint.config.ts
import {defineConfig} from 'oxlint';
import javascript from '@ver0/oxlint-config/javascript.js';
import typescript from '@ver0/oxlint-config/typescript.js';
import react from '@ver0/oxlint-config/react.js';
import browser from '@ver0/oxlint-config/browser.js';
import vitest from '@ver0/oxlint-config/vitest.js';

export default defineConfig({
	extends: [javascript, typescript, react, browser, vitest],
});

🔬 Relationship to @ver0/eslint-config

This package covers what oxlint lints natively. The rest stays with @ver0/eslint-config:

  • Svelte — oxlint only lints <script> blocks of .svelte files; template and runes rules need eslint-plugin-svelte
  • JSON / Markdown — not oxlint's domain
  • Formattingoxfmt replaces Prettier entirely; stylistic lint rules are deliberately absent from these configs

🛠️ Troubleshooting

Rules conflicting with your existing setup? Rules defined next to extends win over the extended configs:

// oxlint.config.ts
import {defineConfig} from 'oxlint';
import javascript from '@ver0/oxlint-config/javascript.js';
import node from '@ver0/oxlint-config/node.js';

export default defineConfig({
	extends: [javascript, node],
	rules: {
		'some-rule': 'off', // Override any rule
	},
});

Your overrides losing to the presets? oxlint merges a consumer's top-level overrides before the extended configs, so preset overrides (e.g. vitest's plugin enablement for test files) win. Compose your own overrides as the last extends entry instead — and note that rules of a plugin enabled only inside an override (like vitest/*) are silently ignored in your override unless it redeclares the plugin:

// oxlint.config.ts
import {defineConfig} from 'oxlint';
import javascript from '@ver0/oxlint-config/javascript.js';
import vitest from '@ver0/oxlint-config/vitest.js';

export default defineConfig({
	extends: [
		javascript,
		vitest,
		{
			overrides: [
				{
					files: ['**/*.test.*'],
					plugins: ['vitest'],
					rules: {
						'vitest/no-disabled-tests': 'off',
					},
				},
			],
		},
	],
});

About

Oxlint configs used in all ver0 projects

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages