The Art Of Being MANIAC
July 29th, 2026 | 7 mins read"A person who has an obsession with or excessive enthusiasm for something." - Oxford
Previously...
Some time ago, I had the opportunity to give a talk on a subject particularly close to my heart: bringing rigor to development through tooling. A topic that, at first glance, might seem pretty mundane... but in practice, determines the mental well-being of an entire development team!
The title of this presentation, "MANIAC", wasn't chosen at random. Behind it are all the tools I'm about to discuss: EditorConfig, Prettier, ESLint, Stylelint, Husky, and of course, the new wave of OXC tools. The idea isn't to sell you an excessively strict configuration, but rather to show you how a few carefully designed files can prevent endless debates, unreadable git diff output, and commits that turn out to be broken the very next morning.
EditorConfig: The Foundation
It all starts (almost) the same way; a team comes together, each developer with their own preferences and favorite editor:
- Dev A ๐งโ๐ป swears by VSCode and its
CRLFline endings - Dev B ๐ฉ๐ผโ๐ป wouldn't leave IntelliJ for anything in the world (
UTF-16encoding included) - And Dev C ๐จ๐พโ๐ป still codes in Vim with
LFline endings (because why not...)
The result? A simple git diff on a single modified file turns into a flood of +512 / -512 lines, burying any Pull Request review under encoding changes that are completely invisible to the naked eye...
The solution here comes down to a single file, tiny but lifesaving: .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
[*.{js,jsx,ts,tsx}]
indent_size = 2
indent_style = space
[src/**.java]
indent_size = 4
indent_style = tab
[*.md]
trim_trailing_whitespace = false
NB: EditorConfig's real strength is being editor-agnostic. Whether you're using VSCode, IntelliJ, or Vim, the file will be read and applied automatically (provided you have the appropriate extension, although most modern IDEs support it natively, without any additional installation). It's literally the common foundation on which everything else can be built.
Prettier: One Style To Rule Them All
Once encoding and indentation are settled, another kind of debate inevitably emerges; this time, about the code style itself:
- "We should use double quotes, they're better", Dev A ๐งโ๐ป announces during a meeting;
- "Why?", replies Dev B ๐ฉ๐ผโ๐ป
- Dev A ๐งโ๐ป, again: "For consistency! The template already uses double quotes..."
- And Dev C ๐จ๐พโ๐ป, who hasn't had the last word yet, argues that single quotes could actually help distinguish views from logic.
The outcome? Another git diff showing +512 / -512 lines, but this time purely stylistic, and disagreements that will never reach a natural conclusion during a team meeting.
This is precisely the Formatter's role: to settle this kind of debate, once and for all. With Prettier (or an equivalent), a configuration file is all it takes to close the subject:
// .prettierrc
{
"arrowParens": "always",
"bracketSameLine": true,
"printWidth": 120,
"singleQuote": false,
"trailingComma": "es5"
}
Once this configuration is in place, prettier --write "src/**/*.{js,jsx,ts,tsx}" is enough to get everyone on the same page, without discussion. And beyond the purely technical side, using a Formatter brings a real psychological benefit: the whole team buys in (since nobody makes decisions alone in their corner), zero friction in Pull Requests, and overall... the team can breathe a little easier.
ESLint: Find And Fix Problems
An essential distinction deserves a mention here (one I bring up whenever I get the chance): A Linter isn't a Formatter! The former detects issues in the code's logic (unused variables, promises that are never resolved, potential vulnerabilities...), while the latter simply formats the code for readability. Confusing the two means missing out on half the benefits of tooling.
Let's take a concrete example:
- Dev A ๐งโ๐ป writes an
async function()without ever using eitherawaitor.then() - Then immediately follows it with
git add . && git commit - A little later, Dev C ๐จ๐พโ๐ป wonders: "Your promise is never resolved!?"
Unfortunately, the damage is done! This can lead to unstable code, silent bugs, and technical debt that quietly builds up. That's exactly what the Linter, ESLint, is supposed to catch beforehand.
// eslint.config.js
import js from '@eslint/js';
import prettier from 'eslint-plugin-prettier';
import reactHooks from 'eslint-plugin-react-hooks';
import tslint from 'typescript-eslint';
export default [
js.configs.recommended,
...tslint.configs.recommended,
prettier,
{
plugins: { 'react-hooks': reactHooks },
rules: {
'no-console': 'error',
'no-unused-vars': 'warn',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn'
}
}
];
NB: Moving from ESLint version 8 to version 9 is no small change. With v8, presets are stacked together, making rules implicit and therefore difficult to maintain over time. With v9, configurations are explicit, rules are visible at a glance, and performance is better.
"S" Is For Stylelint
And what about CSS? ๐ค We tend to forget about it all too often, with so much attention focused on JavaScript and TypeScript. Yet the same pointless debates find their way in:
- Dev A ๐งโ๐ป has no preference for the order of CSS rules "as long as it works"
- Dev B ๐ฉ๐ผโ๐ป prefers to organize
position, thenmarginandpadding, thenwidthandheight, etc... - Finally, Dev C ๐จ๐พโ๐ป systematically separates properties into media queries, considering this more "Mobile-First"
The result? Duplicate .selectors, and readability (especially during reviews) that takes a serious hit... Stylelint addresses the same need, but for stylesheets:
// .stylelintrc
{
"extends": ["stylelint-config-standard"],
"plugins": ["stylelint-order"],
"rules": {
"order/properties-order": ["position", "display", "padding", "margin"]
}
}
Husky: Controlled Commits
Configuring all these tools is great. But you still need to make sure they're actually run! In real life, the team is often well aware that npm run lint exists... but never uses it:
- Dev B ๐ฉ๐ผโ๐ป casually pushes a commit with the message "fix: trust me I'm an engineer"
- Later, Dev C ๐จ๐พโ๐ป complains that "it doesn't work on my machine!"
Once again, unstable code, a โ 3 problems (1 error, 2 warnings) message sitting in a corner, and a CI/CD pipeline that inevitably ends up failing.
This is where Husky ๐ถ comes in, the orchestrator that ensures nothing escapes the Linter's and Formatter's attention, right from the commit:
# .husky/pre-commit
npx lint-staged
// package.json
{
"lint-staged": {
"*.{css,scss}": ["stylelint", "prettier --write"],
"*.{js,jsx,ts,tsx}": ["eslint", "prettier --write"]
}
}
NB: Husky is nothing more than a JavaScript wrapper around native Git hooks (
.git/hooks). Thanks to it, no "questionable" commit can reach the remote repository without first going through linting / formatting. An enforced discipline, admittedly, but one that's completely implicit for the team.
OXC: The Modern Tooling
The JavaScript Oxidation Compiler
The JavaScript/TypeScript ecosystem has recently been experiencing a small revolution, driven by the VoidZero team (founded by Evan You): OXC - "The JavaScript Oxidation Compiler". Two tools in particular are worth a look:
Oxlint, a Linter written in ๐ฆ Rust, up to 50 times faster than ESLint, with type error detection and growing compatibility with the existing ecosystem.
// oxlint.json
{
"extends": ["recommended", "typescript"],
"plugins": ["react"],
"rules": {
"no-console": "error",
"no-unused-vars": "warn",
"react/rules-of-hooks": "error",
"react/exhaustive-deps": "warn"
}
}
And Oxfmt, its formatting counterpart, roughly 30 times faster than Prettier, with native import sorting (no more unnecessary merge conflicts over this kind of detail), plus support for /* JSDoc */ and Tailwind:
// .oxfmtrc.json
{
"arrowParens": "always",
"bracketSameLine": true,
"jsdoc": {
"commentLineStrategy": "multiline"
},
"printWidth": 120,
"singleQuote": false,
"trailingComma": "es5"
}
NB: Oxlint remains compatible with a large portion of ESLint rules, while Oxfmt focuses on simple, deterministic formatting (much like Biome). Native
importsorting prevents merge conflicts while making the file immediately readable. Enough to reasonably raise the question: ESLint or Oxlint? It all comes down to where you draw the line between maturity and speed.
That said, this new generation of tools shouldn't become another excuse to go too far in the opposite direction: Enable 512+ rules! Fix every single warning! No! Enable what actually helps your team instead. Because a simple configuration keeps code clean and maintainable. Being pragmatic doesn't mean being careless; it simply means adapting to practical needs, rather than shutting down every objection in advance in the name of configuration dogma.
Conclusion
Being "MANIAC", then, isn't about pointless perfectionism, but rather a way to ensure consistency, readability, and maintainability in a project at scale. EditorConfig provides the common, editor-agnostic foundation, without requiring any installation. The Formatter (Prettier or Oxfmt) ensures a consistent code style for a healthy team (don't forget to enable your IDE's formatOnSave). The Linter (ESLint, Stylelint, or Oxlint) watches over your code's quality and security (gotta catch 'em all ๐) before deployment. Finally, Husky automates all of this through Git hooks, establishing an implicit discipline without any conscious effort from the team.
And contrary to what you might think, none of this conflicts with pragmatism: quite the opposite, a simple, carefully designed configuration will save you precious time (and a few gray hairs). As for the Backend, if you're working with a JavaScript/TypeScript stack, the same tools apply directly; otherwise, EditorConfig and Git hooks (through scripting) remain your best allies. And what about SonarQube? It all depends on the company context, between short-term code quality and a long-term vision. But that's another story...
