DEV Community

Cover image for Prettier: A Double-Edged Sword for Code Formatting 🎭
nyxb
nyxb

Posted on • Edited on

Prettier: A Double-Edged Sword for Code Formatting 🎭

Table of Contents

  1. Why I Admire Prettier
  2. The Peculiar Situation
  3. The Rigidity of Prettier
  4. The Line Wrap Dilemma
  5. The Prettier and ESLint Saga
  6. An Alternative Approach
  7. Final Thoughts

My Persistent Effort to Articulate My Sentiments 😣

Despite numerous attempts to pen down this post, I've struggled to express my feelings about Prettier. This time around, I'm committed to clarifying my position for future reference.

Disclaimer: I don't oppose Prettier—in fact, I appreciate it.

Why I Admire Prettier ❤️

Prettier is an invaluable tool that has spared me a tremendous amount of time. I'm grateful to the maintainers and contributors who have put in the effort to establish a reliable foundation for neat, consistent code across the developer community. Although the title may seem provocative, I do frequently use Prettier for interactive documentation and playgrounds with technologies like TypeScript and Next.js. Its seamless support for a wide range of languages allows me to effortlessly enhance the appearance of generated code.

The Peculiar Situation ❓

Upon exploring my open-source projects, you might observe that I rarely rely on Prettier for formatting source code. In this post, I intend to elaborate on the reasoning behind this decision:

The Rigidity of Prettier 🧱

Prettier markets itself as "an opinionated code formatter."

Being opinionated implies that it won't cater to everyone's preferences. Prettier enforces numerous hard-coded decisions to offer a minimal configuration interface. While this approach simplifies usage (which is fantastic!) and promotes consistency across projects, it also restricts your ability to fine-tune the appearance of your code.

Although I appreciate most of Prettier's choices, it can be frustrating to encounter formatting decisions that you dislike and cannot work around.

The Line Wrap Dilemma 📏

One aspect that particularly irks me is the automatic wrapping/unwrapping of code based on line length. Prettier employs a printWidth concept, which limits each line to a specified width (80 characters by default). In general, this approach ensures that code fits within a single screen and eliminates the need for horizontal scrolling.

However, I've often found that it compromises readability and complicates git diffs.

In a recent PR review, highlight an example of this issue:
Formatters truly shine in their brilliance, particularly during PR reviews. However, they can also present challenges, such as when a newly added piece of code initiates a line break. The diff, in this case, fails to reveal the actual changes. It would be splendid if diff viewers were Prettier-conscious and considered line breaks as mere spacing.

Example1

Modifying a JavaScript string literal to exceed the printWidth value causes Prettier to wrap the line forcibly. This action disrupts inline diffing and complicates the review process. In another pull request, shortening the string could lead Prettier to unwrap the lines, creating unnecessary noise.

The following image illustrates another example:

Example 2

While the printWidth of 42 is used for demonstration purposes, this issue persists regardless of the printWidth value.

On the left, we have the input code, and on the right, the output from Prettier. It's apparent which one is "more visually appealing." In my opinion, Prettier's strict adherence to its rule hinders code readability and modification, which contradicts the primary objective of formatting—to enhance code readability.

The real issue lies in the fact that this behavior is non-negotiable. You cannot disable it entirely(#3468). Increasing the printWidth merely postpones the problem and affects other files you haven't touched. The only workaround is to use // prettier-ignore, but the "all or nothing" choice defeats the purpose of utilizing Prettier in the first place.

The Prettier and ESLint Saga 🤹

Prettier, as a code formatter, focuses solely on code styles and not logic. Consequently, many projects use ESLint in conjunction with Prettier to check logic as well. If you've ever configured this setup, you might have noticed some overlapping functionality between the two—ESLint can also lint code styles. A common practice is to use eslint-config-prettier to disable overlapping rules in ESLint (other solutions are also available).

However, this approach creates a messy situation for me:

ESLint's auto-fix feature can format code just as effectively as Prettier, but with greater flexibility.

An Alternative Approach 🔄

ESLint is essential to my workflow for ensuring code quality. Since ESLint is already capable of formatting, I prefer to utilize it exclusively.

I dedicated some time to configuring my ESLint and created a config preset:

@nyxb/eslint-config
As a result, the setup configuration can be minimal:

npm i -D @nyxb/eslint-config
Enter fullscreen mode Exit fullscreen mode
// .eslintrc
{
  "extends": "@nyxb"
}
Enter fullscreen mode Exit fullscreen mode

That's all it takes. With IDE extensions, auto-fixing on save is also possible. It functions similarly to Prettier but respects your choices regarding line breaks and adheres to numerous linting best practices. Naturally, it's opinionated to cater to my needs. However, it could serve as a helpful reference for creating your own version.

Final Thoughts 🌅

This post aims to share my personal experiences and opinions. Of course, you may have differing viewpoints and need not agree with me. I'm not criticizing Prettier for its design. Different tools have different purposes and focuses, so there's no definitive "better" or "worse." It's about choosing the right tools for the right situations. I'll continue to be a satisfied Prettier user for cases where I don't require maximum customizability, while exclusively using ESLint for my projects' source code.

I hope this provides clarity and offers some insights. Cheers!

@nyxb/eslint-config repo

cd ..
CC BY-NC-SA 4.0 2023-PRESENT © Dennis Ollhoff

Top comments (0)