Skip to content

💄 @kitql/eslint-config

To have linting & formatting in your project, you need 20 dep, files, … and it’s a pain to maintain in each project.

Here the idea is to reduce as much as possible the config on your end. (Of course, you can still tune things)

Terminal window
npm i -D @kitql/eslint-config eslint oxfmt

You need to install the peer dependencies you want to use (by default: eslint, oxfmt).

@kitql/eslint-config ships optional tools - install only what you want to use:

ToolWhat it doesInstall
eslintLinter (svelte rules, pnpm catalog rules, custom rules)npm i -D eslint
oxfmtFormatter (Rust); every file type, incl. .sveltenpm i -D oxfmt
oxlintFaster linter (Rust); covers most JS/TS rulesnpm i -D oxlint
tsgolintType-aware lint rules for oxlintnpm i -D oxlint-tsgolint

That’s it: no public-hoist-pattern and no need to list every eslint plugin in your own package.json. @kitql/eslint-config ships them as its own dependencies and resolves them internally.

eslint.config.js
import { kitql } from '@kitql/eslint-config'
/** @type { import('eslint').Linter.Config[]} */
const config = [
...kitql(),
{
name: 'app:rules',
rules: {
// Some custom things?
},
},
]
export default config

You can check your config running this tool

Terminal window
npx @eslint/config-inspector
.oxlintrc.json
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"extends": ["./node_modules/@kitql/eslint-config/.oxlintrc.json"],
"rules": {
// Some custom things?
},
}

The shipped config enables @e18e/eslint-plugin + eslint-plugin-depend for modern-JS suggestions (prefer Array.at, Date.now, URL.canParse, …) and the correctness category at error level.

oxfmt has no extends, so pick one of these two.

oxfmt.config.ts (recommended): import the shipped config, override what you need, and get kitql updates for free.

oxfmt.config.ts
import kitql from '@kitql/eslint-config/.oxfmtrc.json' with { type: 'json' }
const { groups, customGroups } = kitql.sortImports
const at = groups.indexOf('aliases')
export default {
...kitql,
// tailwind v4 custom classes (path relative to this file)
sortTailwindcss: { stylesheet: './src/app.css' },
sortImports: {
...kitql.sortImports,
// one more import group, just before the `$*` aliases
groups: [...groups.slice(0, at), 'my-lib', ...groups.slice(at)],
// first match wins, so it goes before kitql's catch-all groups
customGroups: [{ groupName: 'my-lib', elementNamePattern: ['@my-org/**'] }, ...customGroups],
},
}

The spread is shallow: spread kitql.sortImports again when you change a key inside it. No defineConfig: the json import widens strings and fails its types.

.oxfmtrc.json: copy @kitql/eslint-config/.oxfmtrc.json and edit your copy (no kitql updates).

kitql-lint uses oxfmt.config.ts first, then .oxfmtrc.json. The oxc VS Code extension finds both. svelte: true needs svelte installed. Other tweaks: per-file overrides. All options: node_modules/oxfmt/configuration_schema.json.

.prettierignore is read by oxfmt and by the eslint config (the name stays for compatibility).

.prettierignore
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
package.json
pnpm-lock.yaml
package-lock.json
yarn.lock
# Ignore files that are project specific
/db
/src/lib/ROUTES.ts
package.json
scripts: {
"//// ---- BEST PRACTICES ---- ////": "",
"lint": "kitql-lint",
"format": "kitql-lint -f",
}

By default, kitql-lint runs eslint + oxfmt. Use --tools (-t) to change that:

Terminal window
# default - eslint + oxfmt
kitql-lint
# 🦀 add oxlint (with type-aware rules) - the recommended combo for kitql / sveltekit projects.
# eslint stays around for svelte + pnpm catalog rules.
kitql-lint -t oxlint,tsgolint,oxfmt,eslint
# 🦀 pure oxc - no eslint.
# you lose: .svelte linting, pnpm catalog rules.
kitql-lint -t oxlint,tsgolint,oxfmt

In the recommended combo, you’ll have oxlint and eslint both linting .ts/.js files. To avoid duplicate work, enable the oxlint integration in your eslint config:

eslint.config.js
import { kitql } from '@kitql/eslint-config'
export default [...kitql({ oxlint: { enable: true } })]

That disables in eslint every rule oxlint already covers - you only pay for the svelte/pnpm rules that oxlint can’t replace yet.