DEV Community

loading...
Cover image for Prettier and the Beauty of Opinionated Code Formatters

Prettier and the Beauty of Opinionated Code Formatters

g_abud profile image Gabriel Abud ・4 min read

I love Prettier.

It's probably the single tool that has had the biggest effect on my productivity as a programmer (after Git, maybe).

For those of you that don't know, Prettier is an opinionated code formatter for Javascript/Typescript, HTML, JSX, and more. It is lightweight, requires next to no configuration, and automatically formats code for you. Gone are the days where you spend half of your day arguing with co-workers how to nest HTML, what the correct line length is, or whether strings should have single vs double quotes.

This is my Prettier configuration:

module.exports = {
  printWidth: 80,
  singleQuote: true,
  trailingComma: 'es5',
};

Isn't that simple? My settings are a bit opinionated so you can get by with even less!

I use VSCode, so I setup all my projects to format on save. I strongly recommend you do the same if you haven't already. Any modern IDE should have this capability.

Alt Text
There is a strange pleasure in seeing your garbled JSX fit perfectly into place on save.

The Rise of the Opinionated Formatter

Opinionated formatters are great because they eliminate the ongoing flame war nerds and programmers love to have about code formatting. While it's good that we care this much about the quality of our code, overall this is a huge waste of time. Since we started using Prettier on my team, pull request reviews are much more effective and we're no longer having stylistic discussions every. single. week.

We need to start valuing our time more and realize these discussions are a waste of time. While you may be right that God's intention for strings is to use double quotes, it really doesn't matter. The benefit of using them is already outweighed by the time you've wasted discussing it. Leave that discussion and mental baggage to the Prettier team, I promise they've already given plenty of thought to what the best defaults are.

Prettier is not the only code formatter out there. For Python, I use and love Black. Check out this Github repo for alternatives in other languages.

How to Enforce Prettier

There are many ways to enforce Prettier on your team besides having everyone set it up in their IDE. If you are purely a frontend team, you can use husky and lint-staged. If you are working on a full-stack or multi-language team, you can use the pre-commit Python package to run Prettier as a pre-commit hook. That means that any staged files will be Prettified when you commit using git.

Do we need Additional Linting?

In the past, I used ESLint heavily in my frontend projects. Especially with Airbnb's configuration, which tends to be very strict.

The problem with ESLint is that it's too configurable. It doesn't solve the stylistic flame war. It just ends up adding options, which we really need less of. As web developers we already suffer from decision fatigue, having to choose between frameworks, 3rd party libraries, state management, different styling options, REST vs GraphQL, build tools, etc.

An example of ESLint decision fatigue from a real project:

rules: {
  'react/no-unescaped-entities': 'off',
  'no-restricted-syntax': 'off',
  'no-continue': 'off',
  'no-underscore-dangle': 'off',
  'operator-linebreak': 'off',
  'implicit-arrow-linebreak': 'off',
  'react/destructuring-assignment': 'off',
  'react/no-multi-comp': 'off',
  'jsx-a11y/click-events-have-key-events': 'off',
  'jsx-a11y/no-static-element-interactions': 'off',
  'react/jsx-one-expression-per-line': 'off',
  'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true}],
  'react/no-array-index-key': 'off',
}

ESLint rules are often arbitrarily turned on/off based on people's opinion. Either that or you need a whole README devoted to why certain rules are enforced and others are not. Every time you bring on a new developer you are then opening up these decisions to question. This is too much unnecessary mental drain on everyone.

Most of what ESLint enforces is not automatically fixable, unlike Prettier. This makes it clunky to run in CI or as a pre-commit hook. It requires a developer to go and try to fix it themselves, creating additional manual work. Fixing linting issues is not the fun part of coding.

I still think ESLint has some uses, however with Prettier I think those are pretty minimal. My configuration now basically just extends eslint-config-react-app (used by create-react-app) and eslint-prettier (to avoid conflicting Prettier and ESLint rules), and I don't touch any extra rules. I could see myself getting rid of it eventually as Prettier matures.

My .eslintrc.js now looks like this:

module.exports = {
  extends: [
    'react-app',
    'plugin:prettier/recommended',
  ],
}

Simplicity is underrated.

What about you?

Have you found Prettier or opinionated formatters to be as useful for yourself and your team? Do you think ESLint (or additional linting) is necessary and conducive to productivity?

Discussion (23)

pic
Editor guide
Collapse
vladodev profile image
Vladimir Mikulic • Edited

I completely agree with you, Gabriel.
With the rise of VS Code + Prettier, ESLint has lost its effect.
Unused variables/functions, various cases of unformatted code were (and still are) duties of the ESLint, but as you've said ESLint requires manual intervention.

VSCode & Prettier take care of +95% ESLint duties automatically.
For bigger projects, it could still be useful, but for small projects, it's unnecessary overhead.

Collapse
simonmayerhofer profile image
Simon Mayerhofer • Edited

Eslint has a autofix option as well. In my opinion they should definitely used together. Even though prettier has some functionality eslint also checks prettier is a formatter and eslint a linting tool. 2 different things.

Collapse
vladodev profile image
Vladimir Mikulic • Edited

I wasn't comparing Prettier and ESLint, rather VSCode & Prettier Vs ESLint. The two of them combined make ESLint unnecessary, but, again, it might depend on your experience with your tools & programming in general.

Thread Thread
terkwood profile image
Felix Terkhorn

Thanks for posting

Collapse
g_abud profile image
Collapse
jrogers8835 profile image
jrogers8835

Our team is so depressed right now. We love our prettier but our company software quality scans are also formatting opinionated... with different opinions. We can get them synced up, but what a drag. 😬

Collapse
g_abud profile image
Gabriel Abud Author

What kind of opinions? Conflicting Prettier ones or ESLint opinions?

Collapse
jrogers8835 profile image
jrogers8835

I haven't reviewed the differences personally, (my life is mostly meetings these days) but from my understanding it's little things like the scan considers trailing commas a violation but our prettier adds them.

Thread Thread
g_abud profile image
Gabriel Abud Author

Yeah that sounds horrible. Maybe you can make the quality scan ignore your prettier code? Having conflicting formatters is about as bad as having no formatters.

Thread Thread
jrogers8835 profile image
jrogers8835

Yeah we need to talk to the quality team and see if rules can be set by team instead of company wide (not a small company) otherwise we'll have to change our prettier rules to match the scans 😒

Thread Thread
mxldevs profile image
MxL Devs

How about something crazy like having your own team's prettier-formatted code as the dev base, while pushing it to the quality team's spec is the "production" version lol

I worked on some codebase where the target platform only supported ES5 but others wanted to use ES6 so they were transpiling their code from ES6 to ES5 for "production" purposes.

Collapse
eljayadobe profile image
Eljay-Adobe

I use JavaScript Standard Style.

My project uses quite a few languages. C++ is the most prevalent language. Unfortunately, C++ formatting is a favorite bikeshedding topic. We had joked that the only solution was just to use all the styles to make everyone happy.

void Foo(bool condition) {
{  {
    if (condition) {
    {   {
        std::cout << "The condition is true.\n";
    }}  } else {
    {   {
        std::cout << "The condition is false.\n";
    }}  }
}}  }
Collapse
g_abud profile image
Gabriel Abud Author

Is there not a great alternative for C++? github.com/rishirdua/awesome-code-... lists a couple but they don't look all that promising. Prettier is probably going to be more focused on web development so I doubt they'll be adding C++ any time soon.

It's been so long since I've done any C++ but I'm surprised there isn't anything good out there after all these years. Could be a good project idea.

Collapse
eljayadobe profile image
Eljay-Adobe

There is a tool that we're using called clang-format. It does a respectable job at formatting. The problem isn't having a good formatting tool, the problem is reaching a consensus as to what the formatting should be.

All I know, it won't be my preferred formatting style. Because my C++ formatting style is very non-mainstream.

Thread Thread
fredericbonnet profile image
Frédéric Bonnet

Clang-format works great with VScode BTW. It's included in the standard C/C++ extension with sensible default settings although you can use your own or reuse popular styles (e.g. LLVM). I use it on all my projects and it made my life so much easier, formatting C code manually is such a PITA.

Collapse
robole profile image
Rob OLeary

StandardJS is an opinionated linter and formatter (no config), it's aim is to solve the issue you're talking about, but still have linting. I use eslint + prettier atm, and am keen to try out StandardJS to have a single source for both of these functions, and avoid any conflicts

Collapse
g_abud profile image
Gabriel Abud Author

This looks really cool, thanks for sharing!

Collapse
jankapunkt profile image
Jan Küster

I use standardJs, mainly because it was the best opinionated formatter + linter I found at the time. If I would search now I think I would use prettier, too. But I got so comfy with standard that I mostly write this style by default.

It's just a hard one to convince others that the semicolon is in most (unambiguous) situations just not necessary :-D

Collapse
danielkun profile image
Daniel Albuschat

Good post, and I totally agree! I've seen real, deep and long-lasting team conflicts emerge from code formatting. What a waste of mental energy. I double down on what you say and suggest every team use an auto-prettier and never argue about it again.
More energy for solving customer problems!

Collapse
jonrandy profile image
Jon Randy • Edited

Can't stand them TBH - I disagree with so much of the formatting that is apparently 'the best way to do it' and absolutely hate the way I do things being trashed by a code formatter.

Would be nice to have a system whereby the 'main' stored source would be standardised by a formatter but a copy in the individual's own style would be what they see when they edit. Not entirely sure how this would work in practice though

Coding is very much an art form, and artists have their own styles

Collapse
g_abud profile image
Gabriel Abud Author • Edited

I agree somewhat if you write code for yourself, but when you work on a team these stylistic preferences becomes detrimental. It might be an art form for you but when people are having to look at 5 different art forms in the same codebase, it's not easy. The difference between traditional art (thinking like painting) and code is that 99% of the time code is made as part of a team. There are sacrifices you have to make in any team, musicians all agree on the same tempo and key when playing in a band.

There's still room for artistic expression, but you can show that in the implementation of the code itself, not the style.

Collapse
jonrandy profile image
Jon Randy

Hence the system idea. You'd only ever work on a version styled your way. You would of course have to restyle any bits merged in to match your own taste.

I agree that most artistry is exhibited in the way the code actually functions, but the way it's presented can greatly assist you if you have developed your own ways to do it that gel better with your organisational thought processes.

Collapse
zoedreams profile image
☮️✝️☪️🕉☸️✡️☯️ • Edited

Setting up my auto-formatter and auto-doc tools is the first thing i do on a project. Coupled with hot deploy is fierce. i use prettier with much success in parrell with mangle, browserify, eslint, and some gulp scripts (i know). Another layer i have against the eternal battle against tech debt and anti-designs is check-style. I have a dir with a bunch of rules in script files, and report the error before pushing to github... I also take this even farther and integrate git directly into my projects so i do things like 'yarn .' or 'yarn git:push' my favorite is "yarn ," which runs my auto doc and code format.. i figured running it on a single file is a waste. Only takes a few seconds to format that.

npmjs.com/package/stylelint-checks...