10k Bounty for Rewriting Prettier in Rust
twitter.com
twitter.com
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/
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.
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.
Test runners that run new/changed tests first though are cool. Faster feedback on error but still comprehensive.
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).
If you value a clean commit history, then simply reformat as part of the code change. With autoformatting on save (e.g. through prettier), that's a complete non-issue anyways.
in other language, formatters are pretty damn fast. never heard anyone complain about gofmt or cargo fmt
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.
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.
Having built a compiler and typechecker in Rust, I don't know if I'd say that it was "quite good" for it. Going back, I'd still do it again, but it wasn't exactly a cakewalk. Rust's lifetime rules and visceral hatred of referential structs did not make my life easy at all. I definitely took the easy way out with a lot of string copies too.
Perhaps "speed boost" would be a better alternative for your intended meaning.
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
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.
I’d imagine that this call for rewriting prettier is inspired by swc
Not sure if updating prettier will benefit as much as transpilation.
My not-completely-naive guess is an expert optimizer can get the improvement they're looking for with only small parts or maybe even none of it rewritten in another language.
I use <https://github.com/NiklasPor/prettier-plugin-go-template> a bit and I'm not sure what one would have to do to make a plugin for a Rust binary.
That's how my favorite code formatter (dprint) does it.
For that matter though, it's how I would implement just about any plugin, these days, except those that need to exchange large info rapidly (e.g. an editor plugin that needs to operate on every key press).
It's dead easy to implement on the app side, and plugin authors can use an increasing number of higher-level languages to build plugins.
I've seen attempts at zero-copy memory sharing between JS and WASM, but I'm not sure if the same approach would allow different plugins to share memory and communicate via e.g. Cap'n Proto?
https://observablehq.com/@kylebarron/zero-copy-apache-arrow-...
Note: Guillermo Rauch and Wasmer also joined, adding $12,500 extra to the mix (total bounty is $22,500)
prettier can be faster with a better algorithm. then maybe rust can help it take advantage of specific operating system improvements not naturally available to node. regardless, bravo and onwards with more rewrites!
Do you have any examples of this or is there anything in particular that Prettier uses a suboptimal algorithm for?