요즘은 의존성 없는 JavaScript로 개발하는 게 가장 좋은 방향이라 생각함
JS/CSS 표준 라이브러리도 훌륭하고, 정적 분석(TypeScript의 JSDoc 체크), ES 모듈, 웹 컴포넌트 등도 충분히 강력함
사람들은 이 방식이 확장성이나 유지보수에 불리하다고 하지만, 내 경험상 오히려 단순하고 변경이 쉬운 구조를 유지할 수 있었음
나도 몇 년째 이 접근을 실험 중이며, plainvanillaweb.com이라는 튜토리얼 사이트도 만들었음
프레임워크나 빌드 도구가 하는 일 대부분은 브라우저 내장 기능과 바닐라 패턴으로 대체 가능함
다만 이런 방식은 아직 생소한 영역이라, 대부분의 튜토리얼 생태계가 대형 프레임워크 중심으로 돌아가는 게 문제임
실제로 React 코드를 완전 바닐라로 옮겨도 모듈성은 유지되고 코드 길이는 약 1.5배 정도 늘 뿐, 의존성이 없어서 성능은 오히려 좋아짐
물론 의존성이 나쁘다는 건 아님. 다만 많은 개발자가 “반드시 써야 한다”는 고정관념에 갇혀 있음
단순한 마케팅 페이지라면 가능하지만, 기능이 많은 앱이라면 의존성이 필수적인 경우가 많음
예를 들어 나는 지도 기능이 많은 사이트를 만드는데, mapbox/maplibre/openlayers 같은 대안 없는 라이브러리를 써야 함
2022년에 이 방식으로 프로젝트를 진행했는데, CVE나 버전 마이그레이션 관련 문제는 전혀 없었음
클라이언트도 마이그레이션 비용을 한 푼도 내지 않았음
컴포넌트 렌더링은 쉽지만, 프레임워크의 핵심은 모델의 반응형 업데이트 제공임 이 글처럼 모델 업데이트를 어떻게 처리하는지 궁금함
20년 가까이 JS를 다뤄왔는데, 결국 최소한의 의존성만 두고 나머지는 직접 만드는 방식으로 정착했음
오히려 대규모 코드베이스를 적은 인원으로 유지하기가 더 편해졌음
요즘 도구들 덕분에 예전보다 직접 구현이 훨씬 쉬워졌고, agentic engineering과도 잘 맞음
글이 잘 쓰였고, 감정적이지 않으면서 문제를 명확히 설명함
JS가 “표준 라이브러리”를 제대로 갖추지 못한 게 이런 상황의 일부 원인이라 생각함
요즘 JS 표준 라이브러리가 꽤 방대해졌는데, 아직 어떤 기능이 부족하다고 보는지 궁금함
나는 오히려 격한 글(rant) 을 좋아함. 사람들의 감정뿐 아니라 그 이유를 이해하는 데 도움이 됨
좋은 글이지만, 문제의 근본은 불필요한 추가(=bloat) 자체라고 생각함
“완벽함은 더 이상 추가할 게 없을 때가 아니라, 더 이상 뺄 게 없을 때 이루어진다”는 생텍쥐페리의 말을 인용하고 싶음
대부분의 소프트웨어는 “어떻게 더 우아하게 만들까?”보다 “어떻게 더 쉽게 추가할까?”를 묻는 식으로 작성됨
답은 언제나 npm i more-stuff임
커트 보니것의 글쓰기 규칙처럼, “모든 문장은 캐릭터를 드러내거나 행동을 전진시켜야 한다”는 원칙을 떠올림 데모스테네스와 키케로의 대비처럼, 덜어낼 수 없는 코드가 좋은 코드임
모든 소프트웨어에 불필요한 부분이 있지만, 특히 npm 패키지와 웹앱이 심함
JS는 과거와 미래 브라우저 호환성을 모두 고려해야 하고, UI 중심 언어라 접근성·국제화·모바일 지원 등으로 부피가 커짐
많은 경우 이건 숨겨진 기술 부채 문제로 보임
컴파일 타깃을 ESx로 안 올리고, 패키지나 구현을 업데이트하지 않는 게 원인임
ES5는 이미 13년째 모든 브라우저에서 지원됨 (caniuse.com/es5)
실제로는 오래된 JS 엔진을 지원하려는 사람과, 수많은 미니 패키지를 만드는 사람이 있음
둘 다 자신들의 행동을 기능이라 여기고, 인기 패키지를 많이 유지함
그래서 바뀌기 어려움. 가끔 커뮤니티가 비판하지만, 그들도 나름 논리를 갖고 있음
ES6 이하 호환성을 유지하려는 욕심이 이상하게 느껴짐
Babel로 구버전으로 트랜스파일하면 코드가 비대하고 느려지며, 정작 옛 브라우저에서는 CSS나 JS 기능 한계로 안 돌아감
심지어 polyfill이 문제를 일으킨 적도 있었음 (BigInt를 처리 못한 지수 연산자 polyfill)
오래된 브라우저뿐 아니라 이상한 브라우저 지원도 필요함
콘솔, TV, 구형 안드로이드, iPod touch, Facebook 내장 브라우저 등 다양한 환경이 존재함
그래서 외부 모듈 하나만 두고, 나머지는 트랜스파일러 설정으로 해결함
웹은 “지금 배포하고 나중에 고치자”는 문화가 강해서, 낡은 의존성이 오래 남음
Angular의 설계 결정처럼, 과거의 구조가 현재의 비효율을 초래하는 경우도 있음
예전엔 비동기 추적을 위해 setTimeout 등을 오버라이드했지만, 이제는 signals로 훨씬 단순하게 처리 가능함
일부 패키지 저자들이 다운로드 수를 늘리기 위해 의존 트리를 인위적으로 쪼갠다고 생각함
7줄짜리 패키지가 존재하는 건 말이 안 됨. lockfile 메타데이터가 코드보다 큼
예전에 create-react-app 의존성 중 5%가 한 저자의 미니 패키지였음 has-symbols, is-string, ljharb 같은 사례가 있음
이런 행위가 단순한 자존심인지, 실제로 이익이 있는지 궁금함
예를 들어 Anthropic은 npm 다운로드 수가 많은 오픈소스 유지보수자에게 무료 Claude를 제공함
보안 측면에서도 심각함. 이런 마이크로 패키지 하나하나가 공격 표면이 됨
다운로드 수 경쟁은 오히려 위험을 키움
예전에 어떤 사람이 조직에 침투해 자기 패키지를 의존성에 추가해 이력서용 스타 수를 올린 사례도 있었음
문화적 문제도 있음. JS 커뮤니티에서는 7줄짜리 코드를 직접 붙여 넣는 걸 “바퀴 재발명”이라 비판함
하지만 다른 문화에서는 그게 오히려 좋은 일로 여겨짐
JS 생태계를 비판하기 전에 30 years of br tags를 읽어보면 좋음
JS와 도구의 진화 과정을 이해할 수 있음
단순히 “JS 개발자들이 문제다”라고 말하는 건 공학적 사고의 결여임
나쁜 현실을 이해하려는 태도는 좋지만, 과도한 수용은 패배주의임
우리는 항상 더 나은 이론과 실천을 고민해야 함
소프트웨어 세계는 빠르게 변하므로, 스스로 “가짜 장례식”을 치르며 낡은 관행을 버릴 필요가 있음
이 글은 개발자를 비난하기보다, 현 상태를 합리적으로 비판하는 글로 느껴졌음
9년 된 Node.js 코드베이스를 관리 중인데, 의존성은 8개뿐이고 모두 하위 의존성 없음
Node 내장 기능을 우선 활용하고, 필요한 부분만 직접 구현함
예전보다 훨씬 안정적이고 스트레스가 적음
Deno의 표준 라이브러리도 훌륭해서, 런타임 기본 기능과 함께라면 몇 개 패키지로도 충분히 앱을 만들 수 있음
JS는 신중하게 접근하면 꽤 괜찮은 언어임
is-string 같은 패키지의 cross-realm 안전성 주장은 이해하지만, 실제로 그런 상황은 드묾
npm이 너무 쉽게 배포를 허용하면서 “모듈을 쪼개서 배포하자”는 철학이 과잉 확장된 게 문제임
소비자는 의존 트리를 감사하지 않고 그냥 설치하므로, 선택적 비용이 기본 비용이 되어버림 ponyfill 문제는 자동화로 해결 가능함
예를 들어 Node LTS 버전에서 이미 지원되는 기능을 자동 감지해 제거하는 Renovate 스타일 봇이 도움이 될 것 같음
사내 PWA의 원칙은 단 하나임:
“Chrome 최신 버전으로 업그레이드하라. 그래도 문제가 있으면 그때 본다”
내부용이라면 이게 맞는 접근임. 회사가 지원 브라우저를 정하면 관리가 쉬움
Safari가 메모리를 덜 쓰는 건 이해하지만, 정책적으로 통일하는 게 효율적임
단순하게 유지하는 게 결국 가장 큰 이득을 줌
“ES3(IE6/7 수준)까지 지원해야 한다”는 말은 정말 이해하기 힘듦
보안상 은행 사이트조차 그런 구형 브라우저를 막아야 함
이런 팀은 대부분 2015년쯤 세팅한 빌드 도구를 아직도 안 바꾼 경우임
Webpack, Babel, polyfill 스택을 업그레이드하는 건 큰 일이라 그냥 그대로 둠
“고장 나지 않았으면 고치지 말자”식 문화임
Hacker News 의견들
요즘은 의존성 없는 JavaScript로 개발하는 게 가장 좋은 방향이라 생각함
JS/CSS 표준 라이브러리도 훌륭하고, 정적 분석(TypeScript의 JSDoc 체크), ES 모듈, 웹 컴포넌트 등도 충분히 강력함
사람들은 이 방식이 확장성이나 유지보수에 불리하다고 하지만, 내 경험상 오히려 단순하고 변경이 쉬운 구조를 유지할 수 있었음
프레임워크나 빌드 도구가 하는 일 대부분은 브라우저 내장 기능과 바닐라 패턴으로 대체 가능함
다만 이런 방식은 아직 생소한 영역이라, 대부분의 튜토리얼 생태계가 대형 프레임워크 중심으로 돌아가는 게 문제임
실제로 React 코드를 완전 바닐라로 옮겨도 모듈성은 유지되고 코드 길이는 약 1.5배 정도 늘 뿐, 의존성이 없어서 성능은 오히려 좋아짐
물론 의존성이 나쁘다는 건 아님. 다만 많은 개발자가 “반드시 써야 한다”는 고정관념에 갇혀 있음
예를 들어 나는 지도 기능이 많은 사이트를 만드는데, mapbox/maplibre/openlayers 같은 대안 없는 라이브러리를 써야 함
클라이언트도 마이그레이션 비용을 한 푼도 내지 않았음
이 글처럼 모델 업데이트를 어떻게 처리하는지 궁금함
오히려 대규모 코드베이스를 적은 인원으로 유지하기가 더 편해졌음
요즘 도구들 덕분에 예전보다 직접 구현이 훨씬 쉬워졌고, agentic engineering과도 잘 맞음
글이 잘 쓰였고, 감정적이지 않으면서 문제를 명확히 설명함
JS가 “표준 라이브러리”를 제대로 갖추지 못한 게 이런 상황의 일부 원인이라 생각함
좋은 글이지만, 문제의 근본은 불필요한 추가(=bloat) 자체라고 생각함
“완벽함은 더 이상 추가할 게 없을 때가 아니라, 더 이상 뺄 게 없을 때 이루어진다”는 생텍쥐페리의 말을 인용하고 싶음
대부분의 소프트웨어는 “어떻게 더 우아하게 만들까?”보다 “어떻게 더 쉽게 추가할까?”를 묻는 식으로 작성됨
답은 언제나
npm i more-stuff임데모스테네스와 키케로의 대비처럼, 덜어낼 수 없는 코드가 좋은 코드임
JS는 과거와 미래 브라우저 호환성을 모두 고려해야 하고, UI 중심 언어라 접근성·국제화·모바일 지원 등으로 부피가 커짐
많은 경우 이건 숨겨진 기술 부채 문제로 보임
컴파일 타깃을 ESx로 안 올리고, 패키지나 구현을 업데이트하지 않는 게 원인임
ES5는 이미 13년째 모든 브라우저에서 지원됨 (caniuse.com/es5)
둘 다 자신들의 행동을 기능이라 여기고, 인기 패키지를 많이 유지함
그래서 바뀌기 어려움. 가끔 커뮤니티가 비판하지만, 그들도 나름 논리를 갖고 있음
Babel로 구버전으로 트랜스파일하면 코드가 비대하고 느려지며, 정작 옛 브라우저에서는 CSS나 JS 기능 한계로 안 돌아감
심지어 polyfill이 문제를 일으킨 적도 있었음 (BigInt를 처리 못한 지수 연산자 polyfill)
콘솔, TV, 구형 안드로이드, iPod touch, Facebook 내장 브라우저 등 다양한 환경이 존재함
그래서 외부 모듈 하나만 두고, 나머지는 트랜스파일러 설정으로 해결함
예전엔 비동기 추적을 위해 setTimeout 등을 오버라이드했지만, 이제는 signals로 훨씬 단순하게 처리 가능함
일부 패키지 저자들이 다운로드 수를 늘리기 위해 의존 트리를 인위적으로 쪼갠다고 생각함
7줄짜리 패키지가 존재하는 건 말이 안 됨. lockfile 메타데이터가 코드보다 큼
예전에 create-react-app 의존성 중 5%가 한 저자의 미니 패키지였음
has-symbols, is-string, ljharb 같은 사례가 있음
예를 들어 Anthropic은 npm 다운로드 수가 많은 오픈소스 유지보수자에게 무료 Claude를 제공함
다운로드 수 경쟁은 오히려 위험을 키움
하지만 다른 문화에서는 그게 오히려 좋은 일로 여겨짐
JS 생태계를 비판하기 전에 30 years of br tags를 읽어보면 좋음
JS와 도구의 진화 과정을 이해할 수 있음
단순히 “JS 개발자들이 문제다”라고 말하는 건 공학적 사고의 결여임
우리는 항상 더 나은 이론과 실천을 고민해야 함
소프트웨어 세계는 빠르게 변하므로, 스스로 “가짜 장례식”을 치르며 낡은 관행을 버릴 필요가 있음
9년 된 Node.js 코드베이스를 관리 중인데, 의존성은 8개뿐이고 모두 하위 의존성 없음
Node 내장 기능을 우선 활용하고, 필요한 부분만 직접 구현함
예전보다 훨씬 안정적이고 스트레스가 적음
Deno의 표준 라이브러리도 훌륭해서, 런타임 기본 기능과 함께라면 몇 개 패키지로도 충분히 앱을 만들 수 있음
JS는 신중하게 접근하면 꽤 괜찮은 언어임
is-string같은 패키지의 cross-realm 안전성 주장은 이해하지만, 실제로 그런 상황은 드묾npm이 너무 쉽게 배포를 허용하면서 “모듈을 쪼개서 배포하자”는 철학이 과잉 확장된 게 문제임
소비자는 의존 트리를 감사하지 않고 그냥 설치하므로, 선택적 비용이 기본 비용이 되어버림
ponyfill 문제는 자동화로 해결 가능함
예를 들어 Node LTS 버전에서 이미 지원되는 기능을 자동 감지해 제거하는 Renovate 스타일 봇이 도움이 될 것 같음
사내 PWA의 원칙은 단 하나임:
“Chrome 최신 버전으로 업그레이드하라. 그래도 문제가 있으면 그때 본다”
Safari가 메모리를 덜 쓰는 건 이해하지만, 정책적으로 통일하는 게 효율적임
“ES3(IE6/7 수준)까지 지원해야 한다”는 말은 정말 이해하기 힘듦
보안상 은행 사이트조차 그런 구형 브라우저를 막아야 함
Webpack, Babel, polyfill 스택을 업그레이드하는 건 큰 일이라 그냥 그대로 둠
“고장 나지 않았으면 고치지 말자”식 문화임