I was looking through the prettier docs and the prettier source code. It essentially has those defined helper functions to layout the text, given an AST. It operates on the level of the whole file, on many elements next to each other. It takes the AST and outputs text, not outputting a modified AST (like ESLint does).

In a similar fashion, I was looking at the ESLint code and some example rule implementations. ESLint works it seems by walking the AST and calling every plugin at every node, if the plugin has a handler for that node type. The plugin then rewires the AST. It doesn't really operate on whitespace or text so much, more on the AST.

They seem extremely close to each other, even though it is recommended to use both. But I'm wondering, what lessons can be learned from the architecture of these and similar linting/formatting tools? If it was done again, could they be combined into one tool?

I am working on a custom language and would like to have code formatting and linting, and taking inspiration from these projects (though the code implementing them is quite complex). It seems to me their ideas can be merged to one underlying formalism, that is, manipulating the AST, and outputting text. I guess you still have two separate things (manipulating the AST, and constructing the output text), but it seems like they could be under one roof so as not to create confusion from a userland perspective. Is it better to keep these two concepts and programs separate, or to combine them?

  • 3
    AFAIK both ESlint and Prettier have pluggable parsers and use a common ESTree standard for operating on the AST. The JavaScript ecosystem is just very vibrant with lots of competition and overlapping efforts. But for your own language, you should definitely prefer a single canonical parser and AST format for either purpose, to avoid wasted effort.
    – JacquesB
    Jun 16, 2023 at 21:10
  • 3
    There are no deep lessons here, the tools have similar technology but different tasks. However, they point to two strategies for dealing with potential issues in the code: alerting the developer, vs fixing them automatically. The latter is not possible for more complex issues. You can turn any code formatter into a linter by not writing the changes to disk but by calculating a diff of the changes instead.
    – amon
    Jun 18, 2023 at 6:30
  • To add to the other comments - synergy and cohesion between tools depends a great deal on the cohesion of a community around the language as a whole. JavaScript's ecosystem is disparate because its community is disparate. Contrast that with a language like C# which is at the other end of the scale for cohesion of its ecosystem. .NET largely revolves around "de-facto standard" tools built by Microsoft (many of which are open source, readily reusable, financially backed by Microsoft, etc.) -- the .NET community has no need to waste time replicating those efforts. Jun 18, 2023 at 13:55

1 Answer 1


The major difference is you can have multiple independent ESLint rules analyzing the same AST node, but you can only have one whitespace formatting per node. Therefore a formatter can run a single pass over the AST and produce an output stream rather than mutate the AST. This is a simpler and faster architecture - and it has to be fast to run on every file save.

There is also a philosophical difference: ESLint is fully customizable and allows you to combine rules however you want, while Prettier is opinionated and deliberately has few configuration options.

But there isn't a fundamental technical reason it has to be two separate tools. ESLint supports rules affecting whitespace, so I suppose all of Prettier could be implemented as ESLint rules. It is also inefficient that both tools parse the code into AST separately if you always run both tools anyway.

There is also a lot overlap between ESLint and TypeScript type checking. They are probably all independent tools because they are developed independently.

For your own language, you probably want to avoid wasted effort, so I would definitely recommend combining it into a single tool chain and use the same parser and AST for type-checking, linting, formatting and compilation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.