There’s a project called “dprint” which you can use in the interim if Prettier is a bottleneck :) It’s a Rust-based code formatting platform with a Prettier plugin (among others). It’s a lot faster than running Prettier directly [1]
The dprint plugin wraps Prettier under the hood so compatibility is good. The perf wins come from formatting files in parallel and incrementally.
I don’t really get it. Prettier isn’t something that you need to run that often on the entire repo; you’re probably just running it on save in a handful of milliseconds or on a pre-commit on hopefully less than 10 files.
There are plenty other tools that often run on the entire repo, like tests, lint, build, type-checking, etc. focus on those. Bun showed that there’s a lot of space for improvement.
Adding on to the other comment about CI setups, when I benchmarked removing eslint-plugin-prettier from my work’s ESLint configuration we saw a 37.5% speedup. On our fairly slow CI agents that ended up being pretty significant (~34s per run).
I _wanted_ to drop the plugin and have Prettier automatically run on as a pre-commit hook (as you suggested) but in the end I lost :) We wound up keeping the plugin and eating the slower pipeline time.
Of course there’s more overhead than just Prettier in this case—the ESLint plugin itself will be contributing towards the added runtime!—but depending on your codebase and CI machines, Prettier can definitely slow things down quite a bit. CI taking over a minute or two is a big drag on developer productivity imo.
Ideal world is that everyone is on board with code formatting as a pre-commit task that only touches modified files so it doesn’t bloat CI unnecessarily, but it’s not always possible :(
I’ve done some research on this in the past. The reason that is so slow is because the eslint plugin runs prettier, does a diff between the result of prettier and the real file and then converts each diff entry into a eslint issues. Most of the pain comes from this remarshaling cost
What we did to avoid that bottleneck was just turn off the prettier eslint rule in CI and just run the `prettier --check` command they recommend in their docs.
We also have it set to only run in changed files which helps a lot.
We generally don't link pre-commit hooks for standards though, hence the CI focus. Too easy to circumvent, and I'd rather pay for an external machine to check it when it matters (pre-merge by doing it on PR commits) than block my devs when it doesn't (every time they commit to a non-main branch).
This is such a waste of electricity IMO. Just occasionally batch-fix all files for syntax. Semantic linting can run in CI, as it's about catching bugs. But formatting is for long-term consistency and doesn't need to be done on every commit.
> The main issue is that none of them match the long tail of formatting logic of prettier. I'm putting up a $10k bounty for any project written in Rust that passes > 95% of the prettier JavaScript tests.
95 % is not the "long tail" in my opinion. Maybe 100 % is too hard, but 95 % is rather low.
TBH this sounds like a great candidate for rewrite - likely millions of hours of runtime/hour. Prettier is written on a platform with a history of such rewrites getting 10x perf increases. The only alternative that comes to mind is Go but I'm not that offended by Rust choice - has pros and cons.
It's not just speed, but also correctness. A quick search in the Prettier repo shows plenty of issues for "undefined is not a function", "cannot read property X of undefined/null", and other such errors that are avoidable in a language with a good type system.
As a (nominally) front-end developer the RIIR movement's energy is similar to how the front-end community approaches things.
Overall Rust and its community have many traits that make them very approachable to people not expected to know anything about systems programming, namely:
-Package manager with a familiar philosophy behind it (and not the sort of hell you have to deal with setting up a C++ development environment).
-Outputs WASM without much bureaucracy and advertises it.
-Friendly compiler messages. I don't recall seeing "perhaps" in a compiler error message before.
The people designing Rust put much effort into making the language as approachable as possible and that's the net effect.
That is not to say this is going to be necessarily successful, but so far the enthusiasm is there.
Some dev workflow tools really benefit from being very fast. And parsing and ast building and the like are actually things that rust is quite good for.
That doesn’t mean it couldn’t be done in other languages, but it’s a weighing of trade-offs. And of course, groups of people, such as developers on socials, are quite sensitive to popularity.
It is a sad moment for me, because I have more difficulties understanding Rust than Haskell, and believe me, Haskell is very difficult already. I know C, Lua, OCaml, Go, and the like, but Rust? Not really. What I hate the most is reference implementations being in Rust instead of C. C is almost like a pseudo-code.
The dprint plugin wraps Prettier under the hood so compatibility is good. The perf wins come from formatting files in parallel and incrementally.
[1] https://david.deno.dev/posts/faster-prettier-with-dprint/
[0]: https://github.com/microsoft/parallel-prettier
There are plenty other tools that often run on the entire repo, like tests, lint, build, type-checking, etc. focus on those. Bun showed that there’s a lot of space for improvement.
I _wanted_ to drop the plugin and have Prettier automatically run on as a pre-commit hook (as you suggested) but in the end I lost :) We wound up keeping the plugin and eating the slower pipeline time.
Of course there’s more overhead than just Prettier in this case—the ESLint plugin itself will be contributing towards the added runtime!—but depending on your codebase and CI machines, Prettier can definitely slow things down quite a bit. CI taking over a minute or two is a big drag on developer productivity imo.
Ideal world is that everyone is on board with code formatting as a pre-commit task that only touches modified files so it doesn’t bloat CI unnecessarily, but it’s not always possible :(
We also have it set to only run in changed files which helps a lot.
We generally don't link pre-commit hooks for standards though, hence the CI focus. Too easy to circumvent, and I'd rather pay for an external machine to check it when it matters (pre-merge by doing it on PR commits) than block my devs when it doesn't (every time they commit to a non-main branch).
The idea is to catch cases where contributors failed to run the tool on save.
On large code bases this can be time consuming.
In CI you only need to lint the files that have changed, or run the tests that depend on code that has changed etc.
This way the time it takes to execute the tests scales with the amount of changes, and not with the total amount of code.
What you just described is running on thousands of machines several times a day.
95 % is not the "long tail" in my opinion. Maybe 100 % is too hard, but 95 % is rather low.
I’d imagine that this call for rewriting prettier is inspired by swc
Not sure if updating prettier will benefit as much as transpilation.
[0] https://swc.rs/docs/benchmarks
Overall Rust and its community have many traits that make them very approachable to people not expected to know anything about systems programming, namely:
-Package manager with a familiar philosophy behind it (and not the sort of hell you have to deal with setting up a C++ development environment).
-Outputs WASM without much bureaucracy and advertises it.
-Friendly compiler messages. I don't recall seeing "perhaps" in a compiler error message before.
The people designing Rust put much effort into making the language as approachable as possible and that's the net effect.
That is not to say this is going to be necessarily successful, but so far the enthusiasm is there.
That doesn’t mean it couldn’t be done in other languages, but it’s a weighing of trade-offs. And of course, groups of people, such as developers on socials, are quite sensitive to popularity.
a) speed. On large codebases each preprocessor (and there may be many) can take a long time
b) Rust has several features which make it quite suitable for writing pasrers and suchlike
[1] https://en.wikipedia.org/wiki/Crab_People