State of JS tooling
As you may have heard, the JS ecosystem is trying to move away from tooling written in JavaScript like eslint
, prettier
and even tsc
for more performant options.
There are lots of tools being developed, from compilers to metaframework plugins but today let's focus on only the formatters and linters offered.
The big names around are biome
, oxc
and an announced Microsoft-developed tsgo
.
The trade-offs
However, none of these tools have matured enough to fully supercede their JS counterparts just yet.
Just look at all the downsides you're getting with any tool you choose
Tool | Shortcomings |
---|---|
oxlint |
|
biome |
|
tsgolint |
|
prettier |
|
eslint |
|
Minmaxing DX
So how can we take advantage of all this tooling without the downsides?
With lots of configuration. Here I present to you the setup you can modify for your needs.
package.json
We'll be using a single command script check
that both lints and formats
{
"scripts": {
"check": "prettier -w . && biome check --write --unsafe . && oxlint -c .oxlintrc.json --fix . && eslint ."
},
"devDependencies": {
"@biomejs/biome": "^2.1.2",
"@prettier/plugin-oxc": "^0.0.4",
"eslint": "^9.32.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-oxlint": "^1.8.0",
"oxlint": "^1.8.0",
"prettier": "^3.6.2",
"typescript-eslint": "^8.38.0"
}
}
.prettierrc
Using oxc parser to for a slight speed up
{
"useTabs": false,
"tabWidth": 2,
"singleQuote": false,
"plugins": ["@prettier/plugin-oxc"],
"printWidth": 100
}
biome.json
Ignore files not in git
{
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
.oxlintrc.json
{
"$schema": "../node_modules/oxlint/configuration_schema.json",
"plugins": ["import", "typescript", "unicorn", "promise", "node"],
"tsconfig": "./tsconfig.json",
"env": {
"browser": true
},
"settings": {}
}
eslint.config.mjs
Skip rules that oxlint
already covers
import js from "@eslint/js";
import prettier from "eslint-config-prettier";
import oxlint from "eslint-plugin-oxlint";
import tseslint from "typescript-eslint";
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
ignores: [
".git/*",
".gitignore",
"node_modules/*",
"target/*",
"**/bun.lock",
"**/eslint.config.mjs",
],
},
prettier,
oxlint.configs["flat/recommended"],
...oxlint.buildFromOxlintConfigFile("./.oxlintrc.json"),
);
Side note on Svelte
Svelte has its own tool it uses for linting, svelte-check
, that comes with the svelte-kit
template.
And as for the formatter, all it takes is prettier-plugin-svelte
to get it working.
Those are slow and very basic but you'll die trying to set up anything else, don't even bother.
{
"useTabs": false,
"tabWidth": 2,
"singleQuote": false,
"plugins": ["@prettier/plugin-oxc", "prettier-plugin-svelte"],
"printWidth": 100,
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}
Conclusion
And that's it. Leave a comment if you know a way to optimize these further.
Though we all know, the real setup you'll end up using is no tooling at all LMAO.
Top comments (0)