Refactoring English: Month 12

Michael Lynch

Refactoring English: 12개월 차

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

한 줄 요약

좋아, 그럼 아기 사진 공유 앱은 내가 직접 만들지 뭐.

하이라이트

  • 해커 뉴스(Hacker News) 프런트 페이지에 오를 글을 예측하는 게임을 만들고 있다.
  • 괘씸해서 가족 사진 공유 앱을 직접 만들고 있다.
  • 키보드 중심 윈도우 매니저로 갈아탔다.

목표 달성 성적표

매달 초에 달성하고 싶은 목표를 정한다. 이번 달 결과는 다음과 같다:

책 챕터 두 개 새로 집필하기

  • 결과: 챕터 한 개 집필 완료
  • 성적: C

디자인 문서(design docs) 챕터에서 막혔다. 다루고 싶은 내용이 너무 많고, 그중 일부를 어떻게 풀어내야 할지, 또 얼마나 책에 넣어야 할지 정하기가 어렵다.

문제 중 하나는 챕터 분량이 너무 길어서 한 번에 다루려니 부담스럽다는 것이다. 그래서 챕터를 더 작은 단위로 쪼개 하나씩 집중하는 것으로 계획을 바꿨다. 남은 챕터들은 무엇을 쓸지 감이 좀 더 잡히기 때문에, 이 챕터가 마지막으로 어려운 고비가 될 것 같다.

독자 10명에게 연락하기

  • 결과: 두 명에게만 연락했고 (한 명이 답장했다).
  • 성적: D

즐겁게 하고 유용한 피드백도 얻는데도 계속 미루고 있다. 초기 부담을 줄이면 더 자주 하게 되지 않을까 싶어, 관련 실무 작업을 계속 자동화하고 있다.

Refactoring English 웹사이트로 사람을 끌어올 툴이나 블로그 글 만들기

3,508명이 글을 읽었으니 새로운 독자를 끌어오는 데는 어느 정도 성공했다. 내가 다룬 원작자 밥 니스트롬(Bob Nystrom)이 내 글을 마음에 들어 해서 뿌듯했다. 설령 글이 별 반응을 못 얻더라도, 적어도 밥 니스트롬에게 그의 작업에 얼마나 감사하는지 전할 수 있겠다고 생각했다.

Refactoring English 지표

지표2025년 10월2025년 11월변화
순 방문자 수22,3987,608-14,790 (-66%)
사전 주문 수익$570.75$1,018.48+$447.73 (+78%)
스폰서 수익$48.25$48.25$0.00 (0%)
총수익$619.00$1,066.73+$447.73 (+72%)

방문자와 판매 측면에서 11월은 좋은 달이었다. 방문자 수는 10월보다 소폭 줄었지만, 올해 들어 가장 좋은 달 중 하나였다.

블랙프라이데이 30% 할인 행사를 했다. 어디에나 할인을 뿌리는 게 어색하게 느껴져서 메일링 리스트 구독자에게만 알렸다. 그래도 18명이 구매해 총 $359.41의 매출이 발생하며 성공적이었다.

페터 슈피스-크나플(Peter Spiess-Knafl), zeitkapsl 공동 창업자가 블로그 글에서 Refactoring English를 인용했는데, 이 글이 Lobsters에서 1위를 했다. 내 책의 목표가 독자들이 성공적인 블로그 글을 쓰도록 돕고, 책에 만족해 주변에 추천하게 만드는 것이었기 때문에 페터의 글을 보니 기뻤다.

“프런트 페이지에 오를까?” 게임

해커 뉴스를 워낙 자주 보다 보니 프런트 페이지에 오를 스토리를 잘 맞출 것 같은데, 한 번도 제대로 검증해 본 적은 없었다. 그래서 정확도를 시험해 볼 게임을 만들었다.

게임은 해커 뉴스에 새로 올라온 글을 보여주고, 플레이어가 프런트 페이지에 오를지 아닐지를 예측하는 방식이다:

이 게임의 가장 큰 문제는 스토리가 프런트 페이지에 오르는 데 최대 24시간이 걸릴 수 있다는 점이다. 결과를 24시간 기다려야 하니 재미가 반감된다.

그래서 규칙을 바꿔 게시 후 첫 30분 안에 프런트 페이지에 오를지를 예측하도록 해봤지만, 30분도 여전히 고통스러울 정도로 느리게 느껴졌다.

새로운 아이디어는 글이 올라온 지 10분 후에 잠정 판정을 내리는 것이다. 글의 경과 시간, 추천 수, 댓글 수를 바탕으로 프런트 페이지에 오를 가능성을 대략 계산할 수 있다. 예를 들어 프런트 페이지에 오를 거라 예측했는데 10분 뒤에도 추천이나 댓글이 하나도 없다면, 게임은 일단 틀렸다고 잠정 통보하지만, 이후 24시간 안에 극적으로 반등하면 점수를 되찾을 수 있다.

과거 스토리의 결과를 맞추는 버전도 고민했다. 답이 이미 나와 있으니 즉각 피드백을 줄 수 있지만, 비슷한 게임이 이미 있어 덜 재미있게 느껴졌다. 게다가 내가 노리는 해커 뉴스 골수 팬들에게는 과거 데이터가 오히려 방해가 된다. 프런트에 뭐가 떴는지 어렴풋이 기억하고 있기 때문이다.

괘씸해서 만드는 무료 TinyBeans 대체 앱

아내와 나는 작년에 첫 아이를 낳아 가족에게만 비공개로 아기 사진을 공유할 방법을 찾고 있었다. 친구 중 몇 명은 비슷한 앱을 쓰고 있었지만 모두 광고 기반이었다. 내 아이 사진에 기업 광고가 덕지덕지 붙는다는 생각이 싫어 다른 대안을 찾아봤다.

그러다 TinyBeans를 발견했을 때 드디어 정답을 찾았다고 생각했다. 광고를 없애주는 유료 버전이 있었고, 프라이버시를 핵심 기능으로 내세우고 있었으니 완벽해 보였다.

그런데 막상 써보니 광고 투성이었다. “포토북을 사라!” “개인정보를 더 달라!”는 식이었다.

조금 전 앱을 열었을 때도 내 아이 사진을 보려면 광고 세 개를 일일이 닫아야 했다.

내가 유료 고객인데다 이미 수십 번이나 닫은 광고인데도, TinyBeans는 앱을 열 때마다 거대한 광고 세 개를 띄운다.

알고 보니 가족들은 내가 보는 것보다 더 많은 광고를 받고 있었고, 타사 서비스 광고까지 포함되어 있었다. 최근 가족에게 간 광고 중에는 사기성 짙은 AI 회사에 투자하라는 내용도 있었다:

TinyBeans가 가족에게 이메일을 보낼 때 아들 사진 사이에 이런 스팸성 광고를 끼워 넣는다.

유료 요금제의 “광고 없음” 약속은 나와 아내에게만 해당하고, 나머지 가족에게는 광고와 업셀을 쏟아붓는다.

진작에 TinyBeans를 버리고 싶었지만, 신생아 돌보느라 바빠 새 앱을 찾고 가족을 모두 옮길 여유가 없었다. 그래서 매달 마지못해 TinyBeans에 $9를 내고 있다.

그러다 블랙프라이데이가 왔다.

TinyBeans는 모든 할인 정보는 앱에만 있으니 받은 편지함을 블랙프라이데이 특가로 어지럽히지 않겠다며 스스로를 칭찬하는 이메일을 보내왔다.

TinyBeans는 쓸데없는 이메일로 받은 편지함을 어지럽히지 않겠다며 쓸데없는 이메일을 보낸다.

참 대단하다, 이메일을 얼마나 적게 보내는지 자화자찬하는 이메일이라니.

그런데 그 말조차 거짓이었다! TinyBeans는 이후 앱에서 블랙프라이데이 특가를 확인하라며 이메일을 네 통이나 더 보내왔다:

블랙프라이데이 프로모션으로 폭격하지 않겠다고 약속해 놓고, TinyBeans는 다섯 통의 블랙프라이데이 프로모션 이메일을 보냈다.

결국 참다못해, 괘씸한 마음에 직접 TinyBeans 대체 앱을 만들어 더 이상 돈을 주지 않기로 했다.

“아기 사진 공유 앱을 만들고 싶은 이유는 무엇인가요?”

내가 TinyBeans에서 필요로 하는 기능은 이것뿐이다:

  • 가족이 내가 올린 아기 사진과 동영상을 볼 수 있다.
  • 가족이 이메일로 새 사진과 동영상을 구독할 수 있다.
  • 가족이 사진에 댓글을 달거나 이모지로 반응할 수 있다.

얼마나 어렵겠어? 개발 20시간이면 되지 않을까?

어차피 TinyBeans 웹과 안드로이드 앱은 별로라 떠나게 되어 오히려 반갑다. 그리고 경험 대부분이 이메일 기반이라, 가족이 따로 뭘 하지 않아도 내 앱으로 갈아탈 수 있다.

TinyBeans와 경쟁할 회사를 차리려는 게 아니다. 그냥 TinyBeans 기능을 대체하는 웹 앱 하나 만들고 싶을 뿐이다.

Awesome Window Manager로 갈아타기

개발자로서 부끄러운 비밀 하나는 화면의 창 관리를 잘 못한다는 것이다. 느리고 비효율적인 줄 알면서도 마우스를 과하게 써서 때운다.

작년에 Windows에서 Linux로 갈아타고 49인치 울트라와이드 모니터를 들였다. Windows는 나처럼 마우스를 많이 쓰는 사용자에 맞춰 설계된 반면, Linux 데스크톱은 훨씬 키보드 중심이라 키보드 활용을 소홀히 한 대가가 드러나기 시작했다. 창을 계속 열기만 하고 닫지 않으니 VS Code 창이 10개 넘게, Firefox 창도 10개 넘게, 일회성 계산용 계산기 앱도 5개씩 떠 있게 됐다. 전부 바탕화면 한가운데에 뒤죽박죽 쌓여 있었다.

그쯤 되니 화면 공간을 엄청 낭비하고 창 찾느라 시간을 버리고 있다는 게 분명해졌다. 몇 가지 윈도우 매니저를 써봤지만 계속 문제가 생겼다. 잠금 화면이 동작하지 않거나 모니터의 전체 해상도인 5120x1440을 제대로 활용하지 못하는 식이었다.

내가 본 사람 중 컴퓨터를 가장 빠르게 다루는 사람은 친구 okay zed다. 조언을 구했더니 윈도우 관리에 대한 자신만의 방식을 설명해 줬다. 그의 전략은 가상 데스크톱을 많이 만들어 창을 거의 항상 데스크톱 안에서 전체 화면으로 쓰는 것이다. 그는 xmonad를 쓰지만 내게는 Awesome Window Manager를 권했다.

okay의 단일 목적 가상 데스크톱 철학이 마음에 들어, 이를 바탕으로 Awesome 윈도우 매니저 설정을 만들었다. 블로그용, 책 집필용, 이메일용 등 각각 전용 데스크톱을 두고, 데스크톱당 창을 1~2개로 제한하려 하지만 가끔 뭔가를 찾아보느라 세 번째, 네 번째 창을 띄우기도 한다.

내 블로그 데스크톱은 대체로 이런 모습이다. 편집용 VS Code 창 하나, 결과 확인용 Firefox 창 하나, 그리고 가끔 검색용으로 Firefox 창 하나 더를 띄운다:

기본으로 제공되는 데스크톱 모드가 하나도 마음에 들지 않아 직접 만들었다. 각 창에 화면 너비의 25%를 할당하고, 네 개 넘게 열면 모두 찌그러뜨려 맞춘다. Shift+Win+H와 Shift+Win+L로 창 크기를 수동으로 늘리고 줄일 수도 있다. 다만 Win+L이 화면 잠금 단축키라 가끔 실수로 화면을 잠가버리곤 한다.

Awesome을 몇 주 써본 소감은 이렇다:

  • 좋았던 점
    • 집중력을 높이는 단일 목적 데스크톱을 유지하도록 유도한다.
    • 마우스 클릭 대신 키보드 단축키로 탐색하도록 유도한다.
    • Gnome처럼 절전 모드에서 2% 확률로 충돌하지 않는다.
  • 아쉬웠던 점
    • 모든 것이 Lua로 구현되고 설정되는데, 나는 Lua를 모른다. 설정은 전부 LLM으로 작성하고 있다.
    • 설정이 상당히 로우레벨이라 뷰포트를 넘치지 않게 채우는 같은 로직을 직접 작성해야 한다.
    • 기본 데스크톱 모드가 하나도 마음에 들지 않아 직접 만들어야 했다.
    • 문서가 전부 텍스트라, 그래픽을 다루는 소프트웨어치고는 이상하게 느껴진다.
    • 실수로 충돌하는 단축키를 정의해도 Awesome이 경고를 주지 않는다.
    • Firefox 밖에서 링크를 클릭하면 가끔 현재 데스크톱에 없는 브라우저에서 링크가 열린다. 아마 가장 최근에 건드린 Firefox 창에서 열리는 것 같다.
  • 아직 해결해야 할 점
    • “스크래치패드” 기능을 어떻게 구현할지. 예를 들어 비밀번호 관리자를 플로팅 창으로 띄우거나 계산기를 잠깐 불러 썼다가 닫는 식의 기능이다.
    • 네트워크 연결 상태나 리소스 사용량 같은 위젯을 상태 표시줄에 더 추가하는 방법.

흥미로운 링크

블로그에서 외부 콘텐츠 캐싱하기

Mastodon에서 LGUG2Z와 이야기하던 중 블로그에 트윗을 임베드하는 게 얼마나 성가신지에 대한 얘기가 나왔다. 사용자가 트윗을 삭제하면 내 글에 죽은 콘텐츠가 남는다. 제대로 동작할 때도 독자는 트위터의 트래커를 로드해야 한다. 그간 트윗을 스크린샷으로 때워왔지만 깔끔한 방법은 아니다.

Hugo(내 블로그에 쓰는 정적 사이트 생성기)에서 {<tweet id="12345">} 같은 숏코드로 트윗을 임베드하고, Hugo가 트윗 데이터를 가져와 소스 컨트롤에 저장해서 트위터에 계속 의존하지 않도록 하고 싶다.

LGUG2Z는 이 아이디어를 탐구해 자신의 Zola 블로그에 구현했다. 외부 소스(트윗 등)에서 데이터를 한 번 미리 다운로드하는 스크립트를 실행한 뒤, 블로그 빌드 시점이나 독자 방문 시점에 다시 가져오지 않고도 콘텐츠를 임베드할 수 있다.

LGUG2Z의 솔루션을 Hugo에 맞춰 적용해 보려 했지만 너무 복잡해졌다. 독립 스크립트를 작성해 트위터에서 데이터를 다운로드한 뒤 트윗 같은 UI로 렌더링하도록 했는데, 일반 텍스트 트윗은 그런대로 됐지만 임베디드 미디어나 리트윗이 포함된 트윗에 이르자 불안한 기반 위에 너무 많은 걸 쌓는 느낌이 들었다.

Michael Stapelberg의 Immich 사용기

예전에는 모든 사진을 Google Photos에 저장했다. 프라이버시가 걱정됐지만 다른 어떤 것보다 훨씬 낫다고 느껴 코를 막고 그냥 사진을 모두 맡겼다. 이제는 프라이버시에 더 민감해지고 Google을 더 불신하게 되어 새 사진 업로드는 중단했지만, 대체 서비스를 아직 찾지 못했다.

Immich와 Ente에 대한 좋은 얘기를 들었는데, Michael Stapelberg가 NixOS로 Immich 서버를 구축한 경험을 자세히 쓴 글을 보게 되어 반가웠다.

Firefox 강화된 추적 방지 기능

Firefox가 최근 Enhanced Tracking Protection 기능을 개선했는데, 존재 자체를 몰랐던 기능이었다. 켜보니 uBlock이 허용하던 트래커까지 차단하면서도 오탐은 없었다.

“Rich Friend, Poor Friend”

2022년에 나온 “Rich Friend, Poor Friend”몇 주 전에 올라온 후속 글을 이제야 발견했다. 친구에게 도움을 청하기보다 전문가를 고용하는 방식(예: 친구 대신 이삿짐 업체를 부르기)에 확실히 공감한다.

아마 곡선에서 가장 애매한 구간에 있는 것 같다. 친구에게 이사를 도와달라고 하기엔 충분히 여유가 있지만, 손님을 편하게 맞이할 별채를 둘 만큼 부유하지는 않은 상태랄까.

Deel이 산업 스파이를 고용했다는 추가 증거

Deel 산업 스파이 사건은 내 주변에서 놀라울 정도로 주목을 못 받고 있다.

2025년 3월, Rippling은 자사 직원 중 한 명이 경쟁사인 Deel을 위해 일하는 산업 스파이였다는 사실을 발견했다고 밝혔다. 발각되자 스파이는 화장실로 달려가 휴대폰을 변기에 버리고 물을 내리려 했다.

Rippling은 11월에 업데이트를 올려 Deel이 COO의 아내를 통해 스파이에게 돈을 송금한 은행 기록을 찾았다고 밝혔다. 그 아내는 공교롭게도 또 다른 비윤리적 행보로 유명한 Robinhood의 컴플라이언스 리더였다.

불만족스러운 전 Deel 고객으로서, 그들이 자업자득을 당하는 모습을 보니 속이 시원하다.

마무리

무엇을 해냈나?

배운 점

  • 재미있는 게임을 만들려면 빠른 피드백이 중요하다.
  • TinyBeans는 유료 버전에서도 광고가 실제로 많다.
  • Awesome 윈도우 매니저가 Gnome보다 내 필요에 더 잘 맞는다.

다음 달 목표

  • Refactoring English 웹사이트로 사람들을 끌어올 게임 출시하기
  • Refactoring English 챕터 두 개 집필하기
  • 재미로 만드는 가족 사진 공유 앱을 위한 디자인 문서 작성하기

도움 요청

  • “Will it Hit the Front Page?” 게임 베타 테스트에 관심 있다면 연락해 달라.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글