The Art Of Being MANIAC

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 CRLF line endings
  • Dev B ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป wouldn't leave IntelliJ for anything in the world (UTF-16 encoding included)
  • And Dev C ๐Ÿ‘จ๐Ÿพโ€๐Ÿ’ป still codes in Vim with LF line 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 either await or .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, then margin and padding, then width and height, 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 import sorting 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...