An opinionated config preset for TypeScript, oxlint, oxfmt and commitlint.
- Lint and format with oxlint and oxfmt
- Error on correctness, warn on style
- Carries the recommended presets of upstream ESLint plugins
- Opt-in layers for React, Next.js, Vue, Jest and Vitest
- Import sorting in oxfmt you can extend using
sortImports - Standalone, or using Vite+
- Scaffolds in a single script
npm create @kekkon-nexus/configThe script will detect the config files already in the project and interactively ask for the toolchain and the project scope before writing the new configs or patching the existing ones.
Requires:
- Node.js >= 24.12
- TypeScript 7
Pass flags to skip the prompts:
| Flag | |
|---|---|
--toolchain oxlint|vite-plus |
toolchain to configure |
--scope jest|next|react|vitest|vue |
opt-in preset, repeatable |
--install |
install the packages afterwards |
--module |
add "type": "module" to package.json |
--typescript false|true|strict |
write or patch tsconfig.json |
--type-aware |
install oxlint-tsgolint |
--editorconfig |
write .editorconfig if absent |
--vscode |
write .vscode files if absent |
--commitlint |
write commitlint.config if absent |
Warning
.editorconfig and .vscode support is not matured yet.
Or manually:
npm i -D @kekkon-nexus/config # and other dependencies| Feature | Optional Dependency |
|---|---|
| Formatting | oxfmt |
| Linting | oxlint |
| Type-aware linting | oxlint-tsgolint |
| Unified toolchain | vite-plus |
| Commit linting | @commitlint/cli |
// oxlint.config.ts
import oxlint from "@kekkon-nexus/config/oxlint";
// import react from "@kekkon-nexus/config/oxlint/react";
// import next from "@kekkon-nexus/config/oxlint/next";
// import vue from "@kekkon-nexus/config/oxlint/vue";
// import jest from "@kekkon-nexus/config/oxlint/jest";
// import vitest from "@kekkon-nexus/config/oxlint/vitest";
// import vp from "@kekkon-nexus/config/oxlint/vite-plus";
import { defineConfig } from "oxlint";
export default defineConfig({
extends: [
oxlint,
// Not included, extend them per project
// react, // react, react-perf
// next, // nextjs, extends react
// vue,
// jest,
// vitest,
// vp, // vite-plus plugin, extends vitest
],
});// oxfmt.config.ts
import oxfmt from "@kekkon-nexus/config/oxfmt";
import { defineConfig } from "oxfmt";
export default defineConfig({
...oxfmt,
});Or one config with Vite+:
// vite.config.ts
import oxfmt from "@kekkon-nexus/config/oxfmt";
import oxlint from "@kekkon-nexus/config/oxlint";
import vp from "@kekkon-nexus/config/oxlint/vite-plus";
import { defineConfig } from "vite-plus";
export default defineConfig({
fmt: { ...oxfmt },
lint: { extends: [oxlint, vp] },
});| Import | |
|---|---|
oxlint |
the default set |
oxlint/javascript |
core rules, eslint, oxc and promise plugins |
oxlint/typescript |
type-aware rules, needs oxlint-tsgolint |
oxlint/import |
import hygiene |
oxlint/unicorn |
modern syntax & API preferences |
oxlint/jsdoc |
jsdoc plugin |
oxlint/browser |
jsx-a11y plugin |
oxlint/node |
node plugin |
oxlint/react |
react, react-perf |
oxlint/next |
nextjs, extends oxlint/react |
oxlint/vue |
vue |
oxlint/jest |
jest |
oxlint/vitest |
vitest |
oxlint/vite-plus |
vite-plus plugin, extends oxlint/vitest |
@kekkon-nexus/config/oxlint extends the following:
extends: [
base, // ported upstream recommended presets
javascript, // core rules, eslint, oxc and promise plugins
typescript, // type-aware rules, needs oxlint-tsgolint
import, // import hygiene
unicorn, // modern syntax & API preferences
jsdoc,
browser, // jsx-a11y plugin
node,
]See src/oxlint for the rules each one sets.
{
"extends": ["@kekkon-nexus/config/ts", "@kekkon-nexus/config/ts/strict"]
}Extend either or both. Requires TypeScript 7+.
Options TypeScript 6 already enables by default, like strict, are left unset.
@kekkon-nexus/config/ts sets the following:
@kekkon-nexus/config/ts/strict adds:
{
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
}Sorts into builtins, externals, internals (~/, @/, #/), relatives,
then side effects.
To slot a group in:
import oxfmt, { sortImports } from "@kekkon-nexus/config/oxfmt";
export default defineConfig({
...oxfmt,
sortImports: sortImports({
customGroups: [{ groupName: "react", elementNamePattern: ["^react"] }],
groupsBeforeExternal: [["react"]],
}),
});// commitlint.config.ts
const config = {
extends: [
"@kekkon-nexus/config/commitlint",
"@kekkon-nexus/config/commitlint/gitmoji",
],
};
export default config;MIT License © Kekkon Nexus
{ // Environment "composite": true, "module": "esnext", // Strictness "noImplicitOverride": true, "noUncheckedIndexedAccess": true, // Resolution "verbatimModuleSyntax": true, "rewriteRelativeImportExtensions": true, }