요약
Deno가 멈춰 선 사이 Node가 충분히 현대화해, 이제 Deno를 쓸 이유가 없다는 주장입니다.
웹 개발자 데이비드 부셸이 수년간 쓰던 Deno를 접고 Node로 돌아갔다고 밝혔습니다. 그는 Deno가 몇 년 전부터 혁신을 멈췄고, 그사이 Node가 불편하던 부분을 대부분 고쳤다고 봤습니다.
왜 중요한가
- Node가 TypeScript 실행과 최신 문법 지원을 갖추면서 Deno로 갈아탈 동기가 약해졌다는 진단입니다.
- 실제로 옮겨 보니 코드 몇 곳만 바꾸면 됐다는 점에서, Deno에서 Node로 돌아가는 비용이 작다는 사례이기도 합니다.
핵심 내용
- Deno 운영사가 실리콘밸리식 성공을 좇는 평범한 스타트업이 됐고 직원 절반을 해고했다고 비판했습니다.
- ZSH 연동 오류, 동시 HTTP 요청 처리 버그, JSR(Deno 쪽 패키지 저장소)의 잦은 요청 제한으로 거의 못 쓸 지경이었다고 했습니다.
- 정적 사이트 생성기는 파일 API와 서버 코드 몇 곳만 바꿔 옮겼고, 빌드는 오히려 15% 빨라졌습니다.
- Node는 TypeScript를 바로 실행하지만 node_modules 안에서는 막혀 있어, 패키지는 Tsdown으로 묶어 배포했습니다.
- 악성 패키지를 피하려고 npm 대신 pnpm을 쓰고, 공개된 지 하루가 안 된 패키지는 설치하지 않게 설정했습니다.
HN 반응
- 해고 뒤 로드맵과 소통이 사라졌다며 Deno의 쇠퇴를 아쉬워하는 목소리와, 내장 테스트·린트·포매터 덕에 여전히 Deno를 고른다는 반론이 함께 나왔습니다.
- "TypeScript는 마이크로소프트 제품"이라는 대목에는 npm부터 이미 마이크로소프트 소유라는 반박과 함께, 글의 신뢰도가 떨어졌다는 지적이 이어졌습니다.
저는 [계약직으로] Deno가 표준 라이브러리를 v1에 올리는 일을 도왔고, 그 팀과 철학을 늘 좋아했습니다. 그런데 요즘은 Deno가 서서히 잊혀 가는 듯해서 안타깝습니다. 구조조정 이후로는 로드맵도, 소통도 없는 것 같습니다. 어디로 가려는 건지 정말 궁금하고, 그래도 잘되기를 바랍니다. 저는 Node나 Bun보다 늘 Deno가 더 좋았습니다.
글쎄요, 최근 몇 달 사이 https://celld.dev 주변에서 활동이 꽤 많던데요. 저는 그걸 알게 된 뒤로 Deno 팀을 그 어느 때보다 눈여겨보고 있어요.
https://x.com/rough__sea/status/2105853283617440032
https://youtu.be/G-v1hkQ8Sf8
https://github.com/stars/patcon/lists/awesome-celld
듀러블 오브젝트(durable objects) 쪽에서 계속 뭔가를 만들고 있었던 것 같고, 그게 결실을 맺을 날이 기대돼요.
celld는 아주 흥미롭고, 저도 달이 X에 올리는 글을 계속 따라가고 있습니다. 하지만 deno와 직접 관련된 프로젝트는 아닙니다. 예를 들어 celld 저장소[1]를 보면 Rust가 78.5%라고 나옵니다.
오히려 곁다리 프로젝트에 가깝고, "deno는 어디로 가는가"라는 질문에는 답이 되지 못합니다.
가장 슬픈 점은, 덩치 큰 업체들이 인수를 제안했을 텐데 그걸 거절했을 가능성이 크다는 겁니다. 그런데 시장이 하이퍼스케일러와 자본이 넘치는 AI 기업들에 이렇게 유리한 판에서는 인수가 유일하게 합리적인 선택이었을지도 모릅니다. 팔든가, 밀려나든가 둘 중 하나죠.
JavaScript와 TypeScript 생태계는 유명인과 슈퍼스타의 무대입니다. Deno는 지루한 기술의 길을 걷고 있고요. ESM, 배터리 포함(battery included), 올인원 개발 도구 등 잘한 것이 많았는데도 주목을 잃었습니다. 그러다 보니 또 다른 기술인 Unison이 떠오릅니다. 시대를 앞서갔지만... 이해하는 사람이 많지 않은 기술입니다.
주목을 잃었다기보다는, 그냥 Node로도 충분히 괜찮은데 갈아타서 새로 배우는 비용이 너무 크기 때문이라고 생각해요.
저는 OP의 블로그와 글을 한동안 읽어 왔습니다. 제가 얻은 한 가지는 글이 얼마나 부정적이고 방어적인가 하는 점입니다. 그리고 왜 꼭 그래야 하는지 모르겠습니다.
Bun이나 Deno 같은 것들이 한창 유행일 때도 Node는 묵묵히 자기 일을 해 왔습니다. 조금씩이라도 개선하려고 애쓰는 Node 팀을 저는 존중합니다. 이상적인 런타임은 아니지만 노력하고 있고, 그건 긍정적인 이야기입니다.
제 생각에 저자가 신뢰를 잃은 지점은 여기입니다.
저는 Node(JavaScript)로 작업을 조금 해 봤는데, 많은 라이브러리가 TypeScript 바인딩을 갖추고 있더군요. TypeScript로 옮기라는 압박이 있는 것처럼 "느껴졌습니다." (그리고 Node 작업을 마치면서 내린 결론은, 다음에 Node로 뭔가 제대로 만들 일이 있으면 TypeScript부터 시작하겠다는 것이었습니다.)
저도 잠깐 헷갈렸는데, 패키지에 바인딩(.d.ts)을 허용하느냐, 아니면 라이브러리 소스 자체를 TypeScript(.ts)로 쓰느냐의 차이를 말하는 것 같습니다. 저도 NPM이 라이브러리 소스는 .js 파일로 쓰게 하고 .d.ts를 곁들이도록 강제해야 한다고 봅니다.
당신은 사용자지, Node 생태계의 주인이 아니잖아요.
Bun은 어떤 분야에서는 여전히 한창 인기라고 생각합니다. 저희는 규정 준수(compliance)를 처리하기가 쉽다는 점 때문에, TypeScript를 쓸 때 Node 대신 Bun을 고르는 경우가 많습니다. Bun 런타임, Microsoft Azure, 사내 Node 패키지만으로 API를 만들 수 있어서, Node로 작업할 때보다 NIS2 준수 부담이 훨씬 줄어듭니다.
그렇다고 우리 팀원 중에 TypeScript 쪽에서 스스로를 "Bun" 팀이라고 여기는 사람은 없을 겁니다. 예를 들어 사내 패키지는 전부 Node 패키지입니다.
저는 Bun을 앤트로픽이 소유한 것에 대해 개인적인 의견은 없습니다. 위험 평가 항목에는 들어 있었지만, 당연히 통과했습니다.
규정 준수가 핵심 판단 기준이라면 Deno가 큰 장점이 되지 않나요? 기본 상태로 이미 NIS2를 충족하잖아요. 보안이 Deno의 가장 근본적인 셀링 포인트이고요.
Bun은 Node와 마찬가지로 아무나 믿어 주는(permissive) 신뢰 모델을 씁니다.
궁금한 게 있습니다. Bun은 개발 속도가 빠르고 LTS도, 이전 마이너 릴리스에 대한 지원도 없는데, 그런 상황에서 어떻게 규정 준수 검사를 통과하나요? "부담이 줄어든다"고 하신 이유가 의존성이 적어서라고 이해하면 되는 건가요?
저한테는 Deno가 여전히 쉬운 선택입니다. 테스트 러너(deno test), 린터(deno lint), 타입 체커(deno check)가 기본으로 들어 있으니까요. 예전 프로젝트에서는 이런 용도로 온갖 npm 패키지를 써 봤는데, 새 Node 프로젝트에서 요즘 뜨는 게 뭔지, 올바른 설정이 뭔지 전혀 모르겠어요. 그래서 이 모든 걸 한 번에 해결해 주는 Deno의 단순함이 정말 좋습니다. 또 TypeScript 라이브러리를 배포할 때는 JSR과 Deno 조합이 TypeScript Node 프로젝트를 세팅하고 컴파일된 코드를 배포하도록 설정하는 것보다 여전히 훨씬 쉽습니다. tsdoc 주석으로 문서 페이지까지 만들어 주는데, 저는 JSR 말고는 그걸 어떻게 하는지 알아 본 적이 없어요.
제가 보기에 요즘 가장 핫한 린터는 Oxlint입니다. 우리 모노레포에서 같은 규칙 세트로 eslint보다 말 그대로 300배 빨라졌어요. prettier 대신 Oxfmt와 같이 쓰면 정말 놀랍습니다.
솔직히 eslint(그리고 강박증에 걸린 듯한 prettier)보다 낫다는 건 기준이 정말, 정말 낮은 거죠...
솔직히 "더 좋고 더 빠른" npm 클론은 많았는데도, 여전히 npm이 거의 어디에나 있잖아요.
Oxc 생태계는 여전히 인상적이에요.
말 나온 김에 하나 빠뜨렸는데, 내장 포매터(deno fmt)도 훌륭해요. 다른 프로젝트에서는 Prettier를 쓰고 거기서도 잘 쓰고 있지만, 새 Node 프로젝트마다 의존성을 또 하나 챙겨서 추가하고 설정해야 하는 게 피곤하거든요.
참고로 Node에도 이제 node:test가 있습니다. 다만 린팅과 타입 체크에는 아직 의존성이 필요하긴 합니다.
그런데 node:test는 표준에서 벗어난 아주 형편없는 결정을 몇 가지 했습니다. 저한테는 정말 실망스러웠어요.
단위 테스트는 세상에서 이미 가장 잘 풀린 문제라고 생각하실 겁니다. Jest, Mocha, Vitest 등이 하는 대로 그냥 따라 하면 끝이니까요.
그런데 중요한 기능은 빼먹고, 다른 기능은 "왜 바퀴를 다시 만들었지?" 싶은 이상한 방식으로 구현해 놨습니다 :(
저는 써 보지 않아서 동의하지도 반대하지도 않지만 궁금하네요. 무엇이 빠졌거나 잘못 구현됐다고 보시나요?
솔직히 지금은 기억이 안 납니다. 처음 만져 본 게 몇 달 전인지, 몇 년 전인지 모르겠는데, 그때는 나온 지 얼마 안 됐거든요.
그래도 눈에 띈 게 하나 있는데 .only()입니다. 주요 테스트 프레임워크에서는 개발자가 (가끔) 테스트를 하나씩만 돌리고 싶어 한다는 걸 전제로 합니다. 아주 간단하게, 테스트에 ".only()"를 붙이면 러너가 그 테스트만 실행합니다.
Node에서는 특별한 명령줄 플래그를 넘기거나, 그 테스트 위의 모든 describe에 .only를 붙여야 합니다. 테스트 하나 돌리는 기본 동작이 필요 이상으로 어려워지는데, 얻는 이점은 전혀 없습니다. (다시 말하지만, 다른 테스트 러너들이 하는 방식대로 하면 됩니다.)
그런 기능들은 훌륭하지만, JS/TS를 쓰는 대부분의 사람들이 신경 쓰는 것은 아닙니다.
Node.js에는 내장 테스트 러너가 있고 아주 훌륭합니다. https://nodejs.org/api/test.html
린팅이나 타입 체크까지 런타임이 책임져야 하는지는 잘 모르겠습니다.
여전히 가장 핫한 건 typescript와 eslint예요. 저는 Node에서 10년 넘게 그걸 써 왔고요. 저한테는 오히려 (deno lint)가 새로운 핫한 물건처럼 들리네요.
나쁜 소식이 있습니다(사실 새로운 소식은 아니고, 한참 전에 일어난 일입니다). https://www.cnbc.com/amp/2020/03/16/microsoft-github-agrees-to-buy-code-distribution-start-up-npm.html
그건......제가 아는 누구도 오픈소스 운동과 마이크로소프트의 역사를 그렇게 설명하지는 않을 텐데요.....
걱정하지 마세요. 마이크로소프트는 GitHub를 관리해 온 만큼이나 npm과 그 생태계도 훌륭하게 관리해 줄 거예요.
다행히 GH는 아직 자체 로그인 시스템이 있어서, 마이크로소프트 계정으로 로그인하거나 LinkedIn 프로필을 어떤 식으로든 연결하는 건 (적어도 Github.com에서는) 아예 안 돼요. Linkedin이 만든 공개 Github 앱이야 있겠지만요. 얻을 수 있는 거라도 챙겨야죠.