On Prettier
• upd.
Reasons against enforcing Prettier globally on a code-base. Also applies to other “deterministic”/AST-based reprinting formatters such as Biome or dprint.
-
The way code is formatted also conveys information and programmer’s intent. Unless a specific formatting convention breaks explicit rules, there might be multiple ways of structuring white space in code to convey different kinds of intent.
-
The primary issue is
printWidthenforcement (which cannot be disabled, as it is a “selling point” of the tool). When two lines are similar in function and therefore should look similar, but one sits closer to theprintWidthlimit, Prettier re-formats only that one, breaking the visual parallel.Before:
const disable = () => updateFields({ expanded: true, active: true }) const enable = () => updateFields({ expanded: false, active: false })After Prettier:
const disable = () => updateFields({ expanded: true, active: true }) const enable = () => updateFields({ expanded: false, active: false }) -
Method chains with property extraction get exploded into multi-line blocks for no readability gain.
Before:
export const items = Object .values(lookup) .map(({ name, type, label, category }) => ({ name, type, label, category }))After Prettier:
export const items = Object.values(lookup).map( ({ name, type, label, category }) => ({ name, type, label, category, }) ); -
Intentional chain formatting in E2E tests gets collapsed. A useful convention: first line retrieves the element, subsequent lines describe actions. Prettier destroys this when short chains fit on one line but longer ones don’t.
Before:
cy.get('[data-testid="login-form"]') .find('button') .click() cy.get('[data-testid="settings-panel"]') .find('button') .click() cy.get('[data-testid="upload-dialog"]') .as('uploadDialog') .find('input[type="file"]') .as('fileInput') .scrollIntoView() .attachFile('test.csv')After Prettier:
cy.get('[data-testid="login-form"]').find('button').click() cy.get('[data-testid="settings-panel"]').find('button').click() cy.get('[data-testid="upload-dialog"]') .as('uploadDialog') .find('input[type="file"]') .as('fileInput') .scrollIntoView() .attachFile('test.csv') -
Prefer formatters that surgically target problematic sections of code and allow space for programmer’s opinions on how to format code such as Stylistic.