If you ask the new Grok 4 for opinions on controversial questions, it will sometimes run a search to find out Elon Musk’s stance before providing you with an answer! https://simonwillison.net/2025/Jul/11/grok-musk/
내가 프로그래밍 일을 하면서 갖게 된 몇 가지 경험적 지식이 있다. 오늘은 그 중 하나인 "힙스택 보존 법칙"을 설명해보려 한다. 명제는 간단하다.
힙스택을 3개 이상 고르면, 프로젝트는 산으로 간다.
꽤나 공감이 가는 문장일 거라 생각한다. 특히 주니어 시절 전혀 모르는 기술의 늪에 빠져 토끼굴을 파본 경험이 있다면 말이다. 그렇다면 왜 그런 것일까?
프로젝트의 생애
프로젝트는 탄생한다. 마치 갓난쟁이가 세상을 향해 울음을 터뜨리듯, 새로운 세계를 향해 발을 내딛는다.
이 시점에 프로젝트는 "알려져 있지 않다", 다시 말해 호환성을 확보한, 검증된 프로젝트가 아니다.
예시를 들어보겠다. Svelte(자체 템플릿 언어를 사용하는 웹 프레임워크) 같은 신규 프레임워크가 등장한다면, 기존 린터 도구나 포매터 도구와 처음엔 호환되지 않을 것이다. 어쩌면 사용하고 싶은 프로그래밍 언어가 Svelte 템플릿 언어 내부로 통합되지 않을 수도 있다.
ESLint(자바스크립트 생태계 사실상 표준 린터)같은 힙하지 않은 기술이라면 누군가가 호환 레이어나 플러그인을 만들었을 수 있다. 하지만 Biome(자바스크립트 생태계 신흥 린터 겸 포매터)같은 힙한 기술을 덧붙인다면? 어쩌면 호환성 확보를 위해 당신이 직접 코드를 작성해 연동해줘야 할 수도 있다.
우리는 이러한 호환 레이어 내지는 플러그인 이 충분히 많은 프로젝트를 가리켜 커뮤니티가 크다, 또는 성숙하다 고 부른다.
프로그래밍은 결국 두 퍼즐 조각을 끼워맞춰 연결하는 행위를 포함한다. 서로 다른 생각을 가진 프로그래머가 만든 퍼즐 조각이라면, 그 사이를 연결한 새로운 퍼즐 조각이 필요할 가능성이 높다.
그걸 전부 만드는 야크 털 깎기를 반복하다보면 사람은 지친다. 결국, 프로젝트를 산으로 보내버릴 가능성이 높아지는 셈이다.
힙스택을 쓰려는 자, 그 무게를 견뎌라
그렇다면 힙스택을 3개 이상 고르고도 프로젝트가 제 항로를 벗어나지 않았다면, 왜 괜찮았던 걸까?
크게 두 가지 경우로 나눠 생각해볼 수 있겠다.
충분히 힙하지 않았다. 다시 말해, 성숙한 기술이다. (기술의 안정화)
힙함을 견딜 수 있었다. 다시 말해, 호환 레이어 를 작성할 능력이 된다. (능력의 성장)
위에선 3개 이상이라고 이야기했지만, 능력에 따라 4개, 5개도 괜찮은 사람이 있을지도 모른다.
다른 사람에겐 힙한 기술이, 그에겐 힙하지 않은 기술이 되어버리는 걸지도 모른다.
마치 백독불침, 천독불침, 만독불침의 기인이 되어가듯이.
하지만 그러한 기인이 되기 위해선 약한 독부터 차례로 내성을 길러야 한다.
우리는 그 과정을 학습 이라고 부르기로 했다.
왕관을 쓰려는 자, 그 무게를 견뎌야 하듯, 힙스택을 쓰려는 자. 그 학습의, 충돌의 무게를 견뎌라.
🎉 Big thanks to @2chanhaeng for his first contribution to #Fedify! He implemented the new fedify webfinger command in PR #278, which allows isolated #WebFinger lookups for testing configurations. This addresses the need for developers to test WebFinger functionality without performing comprehensive object retrieval.
The contribution includes:
A new fedify webfinger <handle> command that accepts @user@domain format handles or URIs
Clean JSON output of WebFinger JRD results
Proper error handling for invalid handles and lookup failures
Complete #CLI integration with help text and usage examples
This was originally filed as issue #260 and marked as a good first issue—perfect for newcomers to learn the codebase structure while contributing meaningful functionality. The PR has been merged and will be included in the upcoming Fedify 1.8.0 release.
We appreciate all first-time contributors who help make Fedify better for the entire #fediverse community. Welcome aboard, ChanHaeng!
Gemini로 이런 저런 정신나간 소설들을 작성하는 데 재미를 붙였었는데, 저번에 생성했던 작품은 수위가 제법 있어서 공개하기 꺼려졌지만 이번에 나온 건 그렇지 않아서 기분 좋게 공개할 수 있게 되었다. 그리하여 "산속 무녀들의 비밀"이라는 무녀무녀한 소설을 썼습니다. 홈페이지 레이아웃도 대부분 Gemini로 만들었다(여전히 사람 손길이 좀 필요하긴 했지만). https://w.mearie.org/maidens/
@mck Yeah, I could specify the script instead of the region in the language code, but the internationalization framework I'm using doesn't support it. 😩
If an ideograph has more than one numeric value, the first one is to be considered the most common one, and that first value is used for the Numeric_Value property of the ideograph.
Claude에게 물어보니 지역적이거나 역사적인 이유가 있을 것이라 해서 중국에서 다르게 쓰나 싶었는데, 위키백과 문서들을 참고하니 兆의 의미가 시대에 따라 달라져 왔기도 했고, 표기법(셈법?)에 따라 또 다른 듯 하다. 지금 사용하는 단위마다 10000배씩 변화하는 방식은 만진법이라고 하는 것 같다.
예전부터 기술 스택을 정할 때는 꼭 청개구리 같은 기술을 고르곤 했다. 2000년대 말에 Ruby로 웹 개발을 할 때에는 Rails 대신 Sinatra를 DataMapper와 함께 썼다. JavaScript 프레임워크를 쓸 때도 Prototype 대신 MooTools를 썼다. 2010년대 초반에 Python으로 웹 개발을 할 때는 Django를 안 쓰고 Werkzeug을 SQLAlchemy와 함께 썼다. 요즘에는 React와 Next.js를 안 쓰고 Solid와 SolidStart를 쓴다. 나는 요즘 이렇게 남들 쓰는 기술을 안 쓰고 꼭 삐딱하게 대안 기술만 골라서 쓰는 것을 두고 청개구리 스택이라고 부르고 있다. 아마도 반댓말은 정석 스택 정도가 될 것이다.
청개구리 스택의 가장 큰 특징은 역시 쓰는 사람이 상대적으로 적다는 것이다. 그렇기 때문에 문제를 만날 일이 좀 더 많고, 트러블슈팅을 할 때도 다른 사람이 이미 찾은 해결책을 쓰지 못하고 직접 해결해야 할 때도 많다. 하지만 이것이 곧 그 기술, 그리고 그 기술을 너머서 그 분야에 대한 좀 더 깊은 이해를 갖추게 하는 기회가 되기도 한다. 이를테면, Werkzeug의 추상화 수준이 높지 않아서 그 위에서 사실상 인하우스 웹 프레임워크를 만들어서 써야 했다. 물론, 이를 누군가는 삽질이라고 생각할 수 있겠지만, 그런 “삽질”이 나를 성장시킨 것도 사실이다. Stack Overflow에 답이 없을 때, 소스 코드를 직접 읽어야 했고, 그 과정에서 HTTP 프로토콜의 세세한 부분까지 이해하게 되었다. 그리고 그 기술이 오픈 소스라면, 실제로 그 기술에 기여할 기회도 많이 얻는다. 내가 제출한 풀 리퀘스트가 머지되는 순간의 희열은 정석 스택에서는 느끼기 힘든 것이다.
청개구리 스택의 또 다른 특징은 대체로 후발주자라는 것이다. 즉, 정석 스택에서 불만스러운 부분을 인식한 사람들이 참지 못하고 만든 경우가 많다. 그렇다 보니 대안적인 설계를 하게 된다. Solid가 React의 가상 DOM 오버헤드를 피하기 위해 정밀한 반응성(fine-grained reactivity)을 구현한 것처럼 말이다. 그리고 항상 그런 건 아니지만, 그러한 대안적인 설계가 정석 스택의 설계보다 더 나을 때도 많다. 정석 스택의 잘못된 선택들을 보고 배운 다음 그것들을 피해서 만드는 경우가 많기 때문이다. 이로 인해 청개구리 스택을 선택한 사람은 정석 스택을 선택한 사람보다 그 분야에 대해 조금 더 나은 이해, 좀 더 정돈된 이해를 갖출 기회가 더 많다.
한편, 정석 스택은 많은 경우 종합 선물 세트의 형태를 갖는 경우가 많다. Rails의 “설정보다 관행”(convention over configuration), Django의 “배터리 포함”(batteries included), Next.js의 풀 스택 솔루션을 생각해 보면 내부적으로는 여러 기술들을 품고 있더라도 사용자 입장에서는 그 경계를 느끼지 못할 만큼 잘 통합되어 있는 편이다. 반면 청개구리 스택은 많은 경우 여러 부품을 사용자가 직접 고른 다음 조립까지 해야 하는 경우가 많은데, 이 과정에서 시간이 많이 들긴 하지만 각 부품에 대해 최선을 고를 수 있다는 장점과 함께, 조립하는 과정에서도 각 기술에 대해 좀 더 깊게 이해할 기회가 된다.
이 조립 과정은 때로는 지난하다. Sinatra + DataMapper + Haml + Sass를 조합하면서 각각의 설정을 맞추고, 미들웨어를 연결하고, 오류를 디버깅하는 시간. 하지만 이 과정에서 나는 웹 프레임워크가 실제로 어떻게 작동하는지, 각 계층이 어떻게 연결되는지를 더 깊게 이해하게 되었다. 그리고 그 이해는 나중에 어떤 스택을 쓰든 큰 자산이 되었다.
그러나 한 가지 명심해야 할 것은, 오늘의 정석 스택도 과거에는 청개구리 스택으로 시작했을 수 있으며, 오늘의 청개구리 스택도 미래에는 정석 스택이 될 수 있다는 점이다. Ruby on Rails도 처음에는 Java 웹 개발의 대안으로 부상했고, React도 Backbone.js 같은 과거의 MVC 웹 프런트엔드 프레임워크의 대안으로 주목 받지 않았던가? 즉, 각 기술이 중요하다기 보다는 언제나 새로운 대안에 눈길을 주는 호기심과 기술적인 의사 결정을 할 때 기술 선택의 근거를 그저 대중의 선택에 위임하는 것이 아니라 직접 주체적으로 판단한다는 것이 중요하다고 생각한다.
학습과 추론이 분리되어 있는 LLM의 한계 탓에 앞으로 정석 스택은 더욱 더 정석이 되고, 청개구리 스택의 불리함은 커질 것이다. Claude Code는 Next.js 코드는 술술 짜주지만 SolidStart 코드는 헤맨다. 그럼에도 불구하고 청개구리 스택만이 줄 수 있는 배움의 기회는 여전할 것이라고 생각한다.
LLM 시대에도 나는 계속 청개구리의 길을 걸을 것이다. 왜냐하면 청개구리 스택이 주는 배움의 기회는 단순한 지식 습득을 넘어서, 기술에 대한 좀 더 깊은 이해를 함양하기 때문이다. 그러니 이 글을 읽는 여러분도, 가끔은 Stack Overflow에 답이 없는 길을 걸어보길 권한다. 그 끝에서 만나는 깨달음은 온전히 자신의 것이 될 것이다.