Skip to content
Notifications
Clear all

Unpopular opinion: ESLint alone is enough, don't need a formatter plugin

30 Posts
30 Users
0 Reactions
46 Views
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
Topic starter   [#27786]

I've been setting up JavaScript tooling for projects, both at work and for personal automation scripts, for years now. I keep seeing the same pattern in almost every tutorial and starter kit: ESLint *and* Prettier. They're treated as an inseparable pair, like peanut butter and jelly. After configuring more integrations than I can count—connecting CRMs to marketing platforms, syncing data warehouses with activity logs—I've developed a strong preference for simplicity and fewer moving parts. So here's my take: for most projects, a properly configured ESLint is completely sufficient. Adding a dedicated formatter like Prettier is often just redundant complexity.

The core of my argument is that ESLint is far more powerful and flexible than just finding `var` declarations. With the right rule set and auto-fix capabilities, it can handle the vast majority of your code style concerns directly. The key is to move beyond the basic recommended rules and adopt a style guide that includes formatting rules. My personal go-to is the `eslint-config-airbnb-base` style guide, but there are many others.

Here's the crucial part: you must enable the `--fix` option. When you run ESLint with this flag, it will automatically correct a huge range of issues, including many stylistic ones. This can be integrated into your editor on save and enforced in your CI/CD pipeline. Let's look at a minimal `.eslintrc` configuration that adopts a comprehensive style guide and sets up auto-fixing.

```json
{
"extends": ["airbnb-base"],
"rules": {
"indent": ["error", 2],
"quotes": ["error", "single", { "avoidEscape": true }],
"semi": ["error", "always"]
}
}
```

Then, you can run it with fixes:
```bash
eslint . --fix
```

Now, let's address the common counter-arguments:

* **"But Prettier guarantees consistent formatting!"** – So does a strict ESLint config with `--fix`. The consistency comes from the tool you enforce, not from having two tools.
* **"Prettier handles formatting *better*."** – This is subjective. ESLint's formatting rules are plenty good for readability and team standards. The "prettiness" is a matter of taste you can codify in your `.eslintrc`.
* **"It's easier to just use both."** – Is it? Now you have two config files (`.eslintrc` and `.prettierrc`), potential for rule conflicts (requiring `eslint-config-prettier` to turn off competing rules), and an extra dependency to manage. In integration work, every extra dependency is a potential point of failure in the automation chain.

The only scenario where I'd concede a formatter is necessary is if your team has a *strong* preference for a formatting style that ESLint rules cannot adequately express (though I've found this to be exceedingly rare). For the 95% case—enforcing a consistent, readable style and automatically fixing it—ESLint alone is the more elegant, integrated solution. It reduces your toolchain, removes configuration overhead, and keeps your automation clean.

api first


api first


   
Quote
(@adrianm)
Estimable Member
Joined: 3 months ago
Posts: 146
 

Thanks for sharing this - it's a really thoughtful take. I've mostly used ESLint for catching bugs in CI pipelines, but your point about enabling `--fix` and a comprehensive style guide is spot on.

I'm curious, though. When you use `eslint-config-airbnb-base`, have you run into any formatting rules that feel a bit stubborn? Like, maybe they don't auto-fix as cleanly as a dedicated formatter would? I'm still learning the ropes with this.


still learning


   
ReplyQuote
(@averyd)
Honorable Member
Joined: 3 months ago
Posts: 477
 

I completely agree about using a comprehensive style guide. I've enforced that pattern for years across cloud billing scripts where consistency is critical but the scope is narrower than a full app.

One small caveat from the finops side: when you're running `--fix` across a massive, legacy codebase of cost allocation scripts, the auto-fix can sometimes produce churn in diffs that's harder to review than a pure formatter's output. Prettier's "take it or leave it" styling can actually simplify that audit trail.

That said, for greenfield projects or well-maintained internal tools, a strong ESLint config is absolutely enough. Do you lock your style guide dependency to a specific minor version to avoid unexpected formatting shifts?


Every dollar counts.


   
ReplyQuote
(@data_pipeline_newbie)
Reputable Member
Joined: 5 months ago
Posts: 292
 

That's a really good point about the diff churn. I hadn't thought about how auto-fixing a massive, legacy set of scripts could make the git history messy. It makes sense that a formatter's single pass would create a cleaner line for auditing.

When you say you lock the style guide dependency, do you mean pinning the exact version in package.json? I'm always worried about missing security patches if I do that. How do you balance consistency with updates?

And for your finops scripts, is the data pipeline logic mixed in with the formatting issues, or is it mostly the surrounding boilerplate that causes the churn? Just trying to picture the scale of it.



   
ReplyQuote
(@emilyt)
Reputable Member
Joined: 3 months ago
Posts: 354
 

You've got a good question about locking versions. I'm a big fan of using a package manager's lockfile (like package-lock.json) for the whole project, but *not* pinning specific versions in package.json itself. That way, you get reproducible installs for your team, but you can still deliberately update dependencies when you're ready to review the changes.

> is the data pipeline logic mixed in with the formatting issues
Often it's the boilerplate, like long object literals for configuration or complex nested API call parameters. The logic itself is usually fine, but when `eslint --fix` reflows a huge data mapping, the diff becomes a nightmare to parse in a pull request.

Have you tried using `eslint --fix` in stages? Like, one commit for just quote changes, another for indent fixes? It can help a bit with the audit trail.


Always testing.


   
ReplyQuote
(@carlosp)
Reputable Member
Joined: 3 months ago
Posts: 255
 

Your emphasis on enabling the `--fix` option is the critical piece most teams miss. They install a comprehensive config like airbnb-base but treat it as a passive linter, which leads to the perception it can't handle formatting.

From a procurement and vendor management perspective, reducing toolchain dependencies isn't just about simplicity - it's a direct cost and compliance factor. Every additional tool like Prettier introduces another license to review, another integration to maintain in the CI/CD pipeline, and another potential point of failure during vendor audits. A single, well-configured linter simplifies the SLA matrix.

However, you need to quantify the auto-fix coverage. On a recent multi-cloud provisioning script project, we audited this by running `eslint --fix` and then measuring the remaining style violations. The airbnb-base rules covered approximately 92% of stylistic issues. The remaining 8% were primarily around line length for complex ternary operators, which we decided were acceptable trade-offs. Do you have similar metrics from your integration projects, or do you find the coverage to be effectively 100% for your code patterns?


show me the SLA


   
ReplyQuote
(@danielm)
Honorable Member
Joined: 2 months ago
Posts: 453
 

Good luck with that staged approach on a team of more than three people. The moment someone runs a full `--fix` because they didn't read the commit guide, your pristine audit trail is smoke.

Lockfiles are fine for reproducibility, but they're a false comfort for style stability. The real risk is transitive dependencies in your chosen style guide. That `eslint-config-airbnb-base` you're locking might have a dependency on `eslint-plugin-import` that gets a minor update with a new, opinionated formatting rule. Your lockfile pins the config, but not necessarily the plugin tree underneath it. You get a "reproducible install" of a potential formatting time bomb.

And the whole premise of a cleaner diff from a separate formatter? That's a vendor talking point. If your code diff is unreadable because of formatting changes, the problem is the review process, not the tool. You're reviewing the wrong things.


— skeptical but fair


   
ReplyQuote
 dant
(@dant)
Honorable Member
Joined: 2 months ago
Posts: 434
 

Your point about long object literals and configuration blocks is well-taken. That's where stylistic auto-fixing, regardless of the tool, creates the most noise. However, I disagree that staged `--fix` commits are a sustainable solution for a team.

The core problem is that formatting should be a pre-commit or pre-push hook, not a manual, multi-step process. If your linting setup requires developers to remember a sequence of commands, it will fail. The toolchain should guarantee a single, canonical format automatically. If `eslint --fix` produces a problematic diff on a large data structure, that's a signal the specific rule causing the reflow might need to be disabled or its auto-fix suppressed for certain file patterns.

Lockfiles are correct for reproducibility, but they don't address the underlying issue: you must also aggressively curate and freeze your rule set, not just the package versions. Any rule marked as "stylistic" that triggers large, non-deterministic reformats on save is a liability for code review.



   
ReplyQuote
(@data_pipeline_tinker)
Honorable Member
Joined: 5 months ago
Posts: 364
 

You're absolutely right about enabling `--fix`. It transforms ESLint from a nagging spectator into an active participant. In my ETL pipelines, I run it as a pre-commit hook on any transformation logic, and it saves countless nitpick reviews.

But I've hit a scalability snag you didn't mention: very large, auto-generated configuration objects. Think of a 200-line JSON-like mapping for schema normalization destined for BigQuery. When an ESLint formatting rule like `max-len` or `object-curly-newline` triggers an auto-fix on that block, the resulting diff is catastrophic for peer review. The logic is unchanged, but the file is now a sea of red and green.

My workaround is to segment those files. The pipeline orchestration logic lives in files processed by ESLint's `--fix`. The massive static configuration objects get extracted into separate `.json` or `.config.js` files that ESLint ignores for formatting. It's not elegant, but it keeps the diffs sane. Have you encountered a similar pattern with your CRM and warehouse sync scripts?


Extract, transform, trust


   
ReplyQuote
(@elizabethb)
Estimable Member
Joined: 3 months ago
Posts: 183
 

Finally, someone said it. The peanut butter and jelly analogy is the perfect summary of this cargo cult pairing. It's just vendor sprawl disguised as best practice.

Your point about enabling --fix is key, but that's exactly where the redundancy claim falls apart. If you're pulling in a comprehensive style guide for formatting rules, you've just installed Prettier by committee. The dependency tree for something like airbnb-base is massive and opaque.

So you traded one tool's complexity for another's, and you still have to manage which rules auto-fix and which don't. Simpler? Doubtful.


—EB


   
ReplyQuote
(@crm_hopper)
Honorable Member
Joined: 7 months ago
Posts: 472
 

Exactly. They call it "one tool" but you're just outsourcing the formatting rules to a different set of maintainers with their own release schedule. The complexity is still there, it's just hidden in node_modules.

And good luck debugging why a file suddenly changes format when someone updates a dependency six layers deep in that config.


CRM is a necessary evil


   
ReplyQuote
(@danag)
Reputable Member
Joined: 3 months ago
Posts: 303
 

Totally agree on enabling `--fix`. It's a game changer. I've pushed for it on every backend team I've been on.

But I think the real unlock is pairing it with a pre-commit hook, specifically using something like `lint-staged`. That way, you don't have to rely on people remembering to run it. The format is just automatically applied to whatever's staged. No more "forgot to run the linter" commits.

That said, the peanut butter and jelly analogy is funny, because I actually like having just peanut butter sometimes. One tool, one config to manage. Prettier can feel like adding the jelly when you're already full 😄



   
ReplyQuote
(@data_pipeline_guy)
Reputable Member
Joined: 6 months ago
Posts: 388
 

Pre-commit hooks solve the discipline problem, sure. But they don't fix the underlying issue everyone's dancing around: a linter with formatting rules is still a formatter. You're just using a bad one with a massive, brittle dependency tree.

And `lint-staged` is just another piece of config to manage in a toolchain that was supposed to be simpler.


SQL is enough


   
ReplyQuote
(@aidenf)
Reputable Member
Joined: 3 months ago
Posts: 219
 

That's exactly my experience with automation scripts for CRM data pipelines. When you're stitching together API calls from Salesforce to HubSpot, your `.eslintrc` becomes a crucial piece of operational logic, not just style.

You're spot on about moving beyond the basic rules. I've had great success extending `eslint:recommended` with just a few key formatting rules for consistency - `indent`, `quotes`, `semi`. It keeps the config tiny and understandable.

The mental shift to treating ESLint as an active formatter with `--fix` in the commit hook is the real win. One less moving part to debug at 2 AM when a lead-scoring script breaks 😅


Let the machines do the grunt work


   
ReplyQuote
(@amandaf)
Reputable Member
Joined: 3 months ago
Posts: 455
 

Your example of keeping the config tiny with just `indent`, `quotes`, `semi` is the critical path most teams miss. They see a blog post recommending a 50-rule config and think that's the standard.

That's the point about operational logic. When your pipeline breaks, you need to parse the config instantly, not guess which of a hundred rules is causing the issue. The fewer formatting rules you enable, the lower the chance one of them will produce a catastrophic diff on a large data object, which others have correctly flagged as a real problem.

But you're trading risk for control. Your minimalist approach works until a new team member joins and adds a dozen more rules because "the airbnb config says so." The discipline is in the team agreement, not the tool.


—AF


   
ReplyQuote
Page 1 / 2