3P by GN⁺ | ★ favorite | 댓글 1개
  • JavaScript 코드 포매터 Prettier는 포매팅 로직이 안정권에 가까워지자, Rust 기반 호환 구현을 통해 성능 경쟁을 유도하려 했음
  • 11월 9일 Prettier는 테스트 스위트 95% 통과 조건으로 1만 달러 현상금을 걸었고, Vercel CEO Guillermo Rauch와 napi.rs의 추가로 총액이 2만 2,500달러가 됨
  • Biome은 약 3주 동안 여러 사람이 호환성을 끌어올려 현상금을 받았고, 이 과정에서 Prettier와의 실제 호환 범위가 빠르게 넓어짐
  • 테스트를 맞추는 과정에서 Prettier의 버그와 의심스러운 결정도 드러나, Prettier 쪽에서도 개선할 구체적인 근거가 생김
  • Prettier는 기부금으로 유지보수자 2명에게 월 1,500달러를 지급해 왔지만, 현재 예산은 8개월 런웨이만 남아 추가 기부가 필요한 상태임

Biome이 Prettier 현상금을 받음

  • Prettier는 JavaScript 코드 포매터로, 사람들이 코드를 작성하는 매우 다양한 방식을 세심하게 처리해 널리 채택됨
  • 포매팅 로직은 이미 견고한 상태이며, ternaries 작업이 반영되면 만족스러운 단계에 이를 것으로 봄
  • 다음 과제는 성능 개선
    • Prettier는 본래 빠른 도구는 아니었지만 대부분의 사용 사례에는 충분히 빨랐음
    • 현재 상태에 머무르지 않기 위해 친근한 경쟁 방식으로 개선을 유도함
  • 현상금 조건과 참여

    • 11월 9일, Rust로 작성된 프로젝트가 Prettier 테스트 스위트의 95%를 통과하면 받을 수 있는 $10k bounty를 제시함
    • Guillermo Rauch Vercel CEO가 같은 금액을 더해 총 2만 달러가 됨
    • napi.rs가 2,500달러를 추가함
    • Algora 측은 현상금용 랜딩 페이지를 만듦
  • Biome의 달성 결과

    • Biome 프로젝트가 현상금을 받음
    • 약 3주 동안 12명가량이 모여 호환성을 개선함
    • 자세한 내용은 Biome의 full report에 있음
    • 테스트를 맞추는 과정에서 Prettier의 bugs and questionable decisions도 다수 발견됐고, Prettier는 이를 개선할 수 있게 됨

성능 경쟁이 만든 압박

  • Prettier 팀이 다른 프로젝트에 자금을 건 이유는 성능 경쟁을 만들기 위해서임
    • Prettier는 JavaScript 코드 포매터 분야에서 지배적인 위치였음
    • 경쟁 부족으로 성능 개선과 여러 엣지 케이스 수정에 대한 동기가 적었음
  • 이제 Biome에는 Prettier와 호환되면서 훨씬 빠른 구현이 있으며, 사용자는 전환할 수 있음
  • Fabio Spampinato는 이 챌린지를 계기로 Prettier CLI를 제대로 프로파일링했고, 여러 극단적인 비효율을 발견함
    • 해당 문제들은 연말까지 고칠 예정임

Prettier의 기부금과 유지보수 예산

  • Prettier의 현상금과 지속적인 운영은 여러 개인과 회사의 큰 기부 덕분에 가능했음
  • 주요 회사 기부

    • Indeed: 20,000달러
    • Frontend Masters: 10,850달러
    • Sentry: 10,529달러
    • Salesforce: 10,025달러
    • Airbnb: 8,426달러
    • Cybozu: 6,086달러
  • 주요 개인 기부

    • Shintaro Kaneko: 1,635달러
    • Suhail Doshi: 1,000달러
    • icchiman: 500달러
    • Mariusz Nowak: 270달러
    • Benoît Burgener: 270달러
    • Jeremy Combs: 270달러
    • f_subal: 230달러
    • 이 기부금 덕분에 Prettier는 지난 2년 동안 두 명에게 월 1,500달러를 지급하며 릴리스를 이어 옴
    • Fisker Cheung과 Sosuke Suzuki가 이 역할을 수행함
    • 현재 예산으로는 8개월 런웨이만 남아 있어 추가 기부가 필요한 상태임
    • Prettier를 사용하고 도움을 받았다면 https://opencollective.com/prettier 에 기부할 수 있음
    • Open Collective는 프로젝트 운영에 큰 도움을 줌
    • 유지보수자는 개인 정보를 제공하지 않고 가입할 수 있음
    • 은행처럼 작동하며 전 세계에서 돈을 주고받을 수 있음
    • 세금 문서를 적절히 처리함
    • Prettier는 총 11만 달러를 모았고, 그중 7만 5천 달러를 재분배함
    • 이번 현상금은 일회성이지만, 코드 포매팅 생태계에 에너지를 불어넣어 더 나은 개발자 경험을 만드는 것이 목표임

댓글과 토론

Hacker News 의견들
  • Prettier 팀이 왜 다른 프로젝트에 자금을 대는지는 궁금했지만, 답이 충분히 납득되지는 않음
    Prettier 개선에 현상금을 걸면 되지, Prettier 개선 동기를 만들려고 경쟁 프로젝트를 만드는 이유가 불분명함
    최종 목표가 Prettier를 접고 Rust 기반 도구로 이동시키는 것인지도 궁금하고, 이미 혼란스러운 생태계를 불필요하게 더 쪼개는 것처럼 보임

    • Prettier 개선 현상금이 아니라 별도 프로젝트가 된 데에는 세 가지 이유가 있어 보임
      첫째, Rust로 포매터를 쓰는 일은 Prettier 코드베이스 개선과 성격이 다름. Prettier는 Rust로 작성되지 않았고, Rust는 포매터 구현에 견고한 선택지임이 입증됐으니 목표 자체가 Rust 포매터 작성에 가까움
      둘째, $20k로 Prettier 소유의 Rust 포매터를 써달라는 건 매력적이지 않음. 뛰어난 개발자에게는 100시간 분량 정도라 프로젝트 완성에 부족하지만, 자신이 소유할 프로젝트로 보상받는다면 훨씬 매력적임
      셋째, Prettier가 우승 프로젝트를 소유하면 유지보수 책임도 Prettier 팀에 생김. 원래 만든 팀은 계속 유지할 유인이 줄고, 경쟁도 사라져 생태계가 덜 활발해짐
    • 오픈소스 유지보수자 입장에서는 모두가 내 특정 구현을 쓰는 것보다 문제가 해결되는 것에 더 관심이 있음
      내 코드를 누가 쓴다고 직접 이득이 생기는 것도 아니고, 접근 가능한 해결책을 만들려고 일한 것임. JS 코드 포매팅에 열정이 있다면, 누군가 더 빠른 방식으로 그 문제를 해결해도 꽤 기쁠 것 같음
    • “우리가 기존 강자이고 JavaScript 개발자에게 쓸 만한 대안이 없다”와 “Rust 쪽에서 해냈고 꽤 viable한 대안이 생겼다” 사이에는 큰 차이가 있음
      국소 최적점에서 벗어나는 문제에 가까워 보임. 가장 큰 성능 병목을 보고 개선할 수 있다고 말할 수는 있지만, 객관적으로 더 나은 비교 대상이 없으면 확신하기 어려움
      모방은 가장 진심 어린 칭찬이고, 어려운 문제를 다른 언어로도 풀 수 있다는 사실 자체가 경쟁 과정에서 가치를 만들어냄
      실제 대안이 없으면 완전한 경쟁도 없음. Rust 구현이 테스트 스위트의 5% 이하만 깎아내고도 더 빠르다면, 표준 구현과 비교했을 때 이 문제의 이론적 한계에 대해 많은 걸 알려줌
      이 영역을 깊이 아는 건 아니지만, 다른 언어의 유사 구현이 있으면 얻을 수 있는 무형의 가치가 항상 있다고 봄
    • 서로 다른 관점과 의도를 가진 사람들이 구현하면 새로운 개선 방향이 드러날 수 있음
      https://biomejs.dev/formatter/#differences-with-prettier
      Biome은 Prettier와 같은 결정을 따르지 않고 갈라진 여러 불편 지점을 찾아냈고, 이것만으로도 병렬 개발의 가치가 충분함
    • 제약과 짐이 다른 접근법은 원래 프로젝트에서는 보이지 않던 개선 영역을 찾을 수 있음
      이른바 Prettier식 사고방식에 갇히지 않았기 때문일 수 있음
  • 많은 사람이 이유를 말하면서도 이 부분을 같이 보지 않는 듯함: “모든 테스트를 맞추면서 Biome 프로젝트는 Prettier의 많은 버그와 의심스러운 결정을 발견했고, 이를 개선할 수 있게 됐다”
    내게는 다른 구현을 통해 자기 구현을 sanity check할 수 있게 됐다는 뜻으로 보임

  • 이 소식이 정말 기대됨
    Biome 팀은 Prettier와 95% 호환성을 달성하는 속도가 놀라울 정도로 빨랐음 https://github.com/biomejs/biome/issues/720
    Rust 덕분에 JavaScript 포매팅 속도를 크게 끌어올릴 수 있고, Python 포매터 ruff 흐름을 따르는 셈임
    글에는 없지만 Wasmer도 Biome을 WASIX로 컴파일하는 데 $2,500 현상금을 걸었고, 그 팀이 이를 위해 작업하는 모습을 보는 것도 좋았음
    곧 Biome이 Wasmer에서 돌아가길 기대함: https://wasmer.io/, https://wasix.org/, https://console.algora.io/challenges/prettier

    • WASIX는 처음 봤는데, 읽어보니 JVM의 환생처럼 보임
      이 이해가 맞는지 궁금함. 시스템에 접근할 수 있고 실제 샌드박스가 아니라면 WASIX에서 코드를 실행하는 이점이 무엇인지 모르겠음
    • WASIX로 컴파일 가능하게 하려는 이유를 알고 있는지 궁금함
  • 속도 개선은 언제나 환영하지만, Prettier가 조금 덜 독단적이면 좋겠음
    특히 줄 길이와 관련해 내 포매팅을 그냥 놔두지 않음. Prettier로 포매팅된 코드는 포매팅하지 않은 코드보다 훨씬 덜 읽기 쉽고, rustfmt 같은 다른 포매터에서는 겪지 않는 문제임

    • Prettier 코드가 훨씬 덜 읽기 쉬운 예시가 있는지 궁금함
      나는 그런 문제를 별로 겪지 않았고 Prettier에 꽤 만족해 왔음
    • print width 옵션은 써봤는지 궁금함: https://prettier.io/docs/en/options.html#print-width
    • Prettier의 진짜 문제는 거의 사실상 표준이 됐다는 데 있음
      개인적으로 Prettier를 전혀 좋아하지 않지만 Svelte는 좋아하고, Svelte 공식 포매터는 내가 알기로 Prettier를 씀. 그래서 Svelte에는 Prettier를 쓰고, 다른 몇 가지도 마찬가지임
      사용자가 도구를 선택하는 상황이라면 “매우 독단적이고, 설정을 원하면 다른 데로 가라”는 원칙이 훌륭할 수 있음. 하지만 특정 사용자층에게 사실상 유일한 선택지가 되면 조금 더 설정 가능해야 함
    • 줄 길이와 관련해 Prettier에는 더 교묘한 부작용이 있고, 그래서 독단적인 포매터를 피함
      Prettier는 의도하지 않은 방식으로 diff를 바꿔버림
      구조 분해 할당에서 멤버 하나를 제거해 줄 길이 제한 아래로 내려가면, diff가 0/-1이 아니라 +1/-5가 될 수 있음. 리뷰어는 5줄 삭제와 1줄 추가 사이에서 정확히 무엇이 빠졌는지 바로 보기 어려움
      Git의 대화형 rebase로 이전 커밋의 오타를 고치려 하면, Prettier가 코드 블록 전체를 다시 포매팅해서 다음 커밋들이 적용되지 않을 수도 있음
      pre-commit 훅으로 Prettier를 돌리게 한 뒤 파일의 일부 변경만 stage해 보면 또 재미있는 문제가 생김. 나는 사양하겠음
    • 동의함. 더 나아가 Prettier가 아예 없었더라면 더 나았을 거라고까지 말하고 싶음
  • 아직도 여러 eslint 플러그인이 멀쩡한 린터를 없애고 Prettier로 대체한 게 짜증남
    Prettier는 너무 강압적이고 추론하기 어렵고, 내가 원한 적도 없는 또 하나의 도구임

    • 폐기된 스타일 규칙들은 새 프로젝트로 포팅됐음: https://eslint.style/guide/why
    • 그런 도구의 목적이 바로 스타일 논쟁을 끝내는 데 있음
    • 어떤 경우에 Prettier를 “추론”해야 하는지 잘 모르겠음
      가끔 병합 충돌 문제가 생기는 정도밖에 떠오르지 않음
  • Rust로 포팅하는 흐름이 있긴 하지만, Prettier는 저장할 때마다 실행되므로 속도 향상이 꽤 클 것임
    곧 Biome을 써볼 예정이고, Biome 프로젝트에 축하를 보냄

    • 단일 파일에서 Prettier가 실행될 때 지연을 느낀 적은 없음
      성능이 중요해지는 건 저장소 전체에 포매팅을 돌릴 때임
      대화형 사용에서는 오래 떠 있고 워밍업된 프로세스를 써야 하며, 그러면 Node 시작 시간은 중요하지 않음. 이상적으로는 타입 검사, 린팅, 강조, 포매팅이 하나의 언어 서비스 안에서 매 키 입력마다 증분 파싱을 하고 공유 AST를 갱신해야 함
    • 이 작업은 Python 커뮤니티의 ruff 열기를 떠올리게 함
      넓은 영향을 주는 효율과 속도 개선이 기대됨
    • Prettier가 저장할 때마다 전체가 아니라 변경된 파일에만 실행되도록 lint-staged 도구를 쓰는 걸 추천함
      큰 프로젝트에서는 차이가 매우 큼
  • “이제 다음 중요한 측면인 성능에 집중할 수 있다. Prettier는 본질적으로 빠른 적은 없지만 대부분의 용도에는 충분히 빨랐다. 이 점이 늘 만족스럽지 않았고, 그래서 뭔가 하고 싶었다. 우호적 경쟁보다 나은 방법이 있을까. 11월 9일, Prettier 테스트 스위트의 95%를 통과하는 Rust 프로젝트에 $10k 현상금을 걸었다”
    어떤 것이 Rust로 작성됐다는 사실에서 더 나은 성능이 어떻게 따라오는지 모르겠음. 기존 코드베이스를 Rust로 단순히 트랜스파일하고 보상을 받을 수도 있었을 것임

    • “단순히”라는 단어를 보면, 그 다음에 나오는 일은 단순하지 않을 거라고 생각하게 됨
      정말 단순하다면 굳이 그렇게 수식할 필요가 없기 때문임
      이 경우 JavaScript 코드베이스를 Rust로 트랜스파일하는 게 단순한지 모르겠음. 두 언어는 사고 모델, 사용하는 라이브러리, 코드 작성 방식이 꽤 다르고, JS-to-Rust 트랜스파일러가 존재하더라도 Prettier 규모 코드베이스에 쓸 만큼 견고할지 의심스러움
    • 관용적인 Rust는 비슷해 보이는 JavaScript/TypeScript 코드보다 별다른 최적화 없이도 5~10배 빠른 경우가 많음
      작업에 따라 다르고 항상 그런 것은 아니지만, 문자열 조작을 많이 하는 파서류는 확실히 해당되는 사례임
    • 문자열 처리에서는 Rust가 JS보다 훨씬 빠름
      https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/fasta.html
      https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/knucleotide.html
    • vjeux에게 받은 답은 이랬음: “요즘 Rust로 작성되는 빠른 웹 도구가 많다”
      https://twitter.com/Vjeux/status/1722769322299609565
      나는 납득되지 않고, vjeux가 Rust 유행에 올라탄 것 같음
  • 우승 프로젝트인 Biome은 몇 년 전 Babel 제작자인 Sebastian McKenzie가 시작한 Rome 프로젝트의 포크 또는 이름 변경임
    sebmck가 지난 1년쯤 자리를 비운 듯하고, 많은 프로젝트 리소스 접근 권한이 그에게만 있어서 기여자들이 업데이트할 수 없었기 때문에 포크됐음
    그가 괜찮기를 바라며, 그와 별개로 Biome 프로젝트가 잘 진행되는 것 같아 다행임

  • 왜 꼭 Rust여야 했는지 모르겠음
    그냥 “더 빠른 것”이면 안 됐나? Rust 구현이 실제로 빠른가? Prettier 같은 프로그램에 메모리 안전성이나 누수 같은 게 정말 중요한지도 의문임

    • 특히 HN에는 Rust가 현재 가장 빠르고 안전한 언어라고 생각하는 목소리가 큰 사람들이 많음
      그래서 어느 정도는 “그렇게 말한다면 직접 증명해보라”는 현상금 챌린지였을 수 있음
  • Biome 벤치마크가 어딘가에 있는지 궁금함
    Prettier보다 정확히 얼마나 성능이 좋은가?