Refactoring English: Month 12

Michael Lynch

Refactoring English: 12개월 차

한 줄 요약

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

하이라이트

  • Hacker News 프론트 페이지에 오를 글을 예측하는 게임을 만들고 있다.
  • 괘씸한 마음에 가족 사진 공유 앱을 만들고 있다.
  • 키보드 중심 윈도우 매니저로 갈아탔다.

목표 달성도

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

책 챕터 두 개 새로 집필하기

  • 결과: 챕터 하나를 새로 발행했다
  • 성적: C

디자인 문서 챕터에서 막혀 버렸다. 다루고 싶은 내용이 너무 많은데, 일부는 글로 풀어내는 데 어려움을 겪고 있고 어디까지 책에 넣어야 할지 결정하기도 쉽지 않다.

문제 중 하나는 챕터가 너무 길어서 한 번에 다루려니 압도된다는 점이다. 새로운 계획은 챕터를 더 작은 단위로 쪼개 하나씩 집중하는 것이다. 남은 챕터들은 무엇을 쓸지 감이 잡혀 있어서, 이 챕터가 마지막으로 어려운 고비일 것 같다.

독자 10명에게 연락하기

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

이 일은 하면서도 즐겁고 유용한 피드백을 얻는데도 계속 미루게 된다. 초기 마찰을 줄이면 더 자주 하게 되지 않을까 싶어 관련 실무를 계속 자동화하고 있다.

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

3,508명이 글을 읽었으니 새로운 독자를 끌어오는 데는 어느 정도 성공했다. 내가 다룬 원작자인 Bob Nystrom이 내 글을 마음에 들어 했다는 점이 특히 기뻤다. 설령 글이 별 반응을 얻지 못하더라도, 적어도 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위를 차지했다. Peter의 글을 보니 기뻤다. 이 책에 대한 내 계획은 독자들이 성공적인 블로그 글을 쓰도록 돕고, 책에 충분히 만족해서 주변에 추천하게 만드는 것이었기 때문이다.

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

Hacker News를 워낙 자주 읽다 보니 프론트 페이지에 오를 글을 꽤 잘 맞출 수 있을 것 같았는데, 한 번도 제대로 검증해 본 적은 없었다. 그래서 정확도를 시험해 볼 게임을 만들었다.

게임은 Hacker News에 새로 올라온 글을 보여주고, 플레이어가 그 글이 프론트 페이지에 오를지 예측하게 한다.

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

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

새로 생각한 방법은 글이 올라온 지 10분 뒤에 잠정 판정을 내리는 것이다. 글의 경과 시간과 추천 수, 댓글 수를 보면 프론트 페이지에 오를 가능성이 있는지 대략적인 확률을 계산할 수 있다. 예를 들어 프론트 페이지에 오를 거라고 예측했는데 10분이 지나도 추천이나 댓글이 하나도 없으면, 게임이 일단 틀렸다고 알려주되 이후 24시간 안에 기적적으로 반등하면 점수를 다시 돌려주는 식이다.

과거 글의 결과를 맞히는 버전을 만들까도 고민했다. 정답이 이미 나와 있으니 즉각 피드백을 줄 수 있지만, 이미 비슷한 게임이 있어서 덜 재미있게 느껴졌다. 게다가 이 게임이 노리는 Hacker News 마니아들에게는 과거 데이터가 오히려 재미를 망친다. 프론트에 떴던 글이 무엇인지 어렴풋이 기억하고 있기 때문이다.

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

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

그러다 TinyBeans를 찾았을 때 제대로 된 앱을 찾았다고 생각했다. 광고를 없애 주는 유료 버전이 있었고, 프라이버시를 핵심 기능으로 내세우고 있었다. 완벽했다!

그런데 막상 써 보니 광고 천지였다. “포토북을 구매하세요!” “개인정보를 더 제공해 주세요!”

방금 앱을 열었는데 내 아이 사진을 보려면 광고 세 개를 각각 닫아야 했다.

유료 고객인데도, 수십 번이나 닫았던 바로 그 광고 세 개가 앱을 열 때마다 크게 뜬다.

게다가 내 가족들은 나보다 더 많은 광고를 받고 있었고, 그중에는 제3자 서비스 광고도 있었다. 최근 가족에게 간 광고 중에는 수상한 AI 기업에 투자하라는 내용도 있었다.

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 Window Manager 설정을 만들었다. 블로그 전용 데스크톱, 책 집필 전용 데스크톱, 이메일 전용 데스크톱 식으로 나눠 쓴다. 데스크톱 하나당 창을 1~2개로 제한하려 하지만, 뭔가를 찾아볼 때는 세 번째나 네 번째 창을 띄우기도 한다.

내 블로그 데스크톱은 대체로 이렇게 생겼다. 편집용 VS Code 창 하나, 결과 확인용 Firefox 창 하나, 그리고 가끔 검색용 Firefox 창 하나가 더 있다.

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

Awesome을 몇 주 써 본 소감은 다음과 같다.

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

흥미로운 링크

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

Mastodon에서 LGUG2Z와 대화하다가 블로그에 트윗을 임베드하는 게 얼마나 성가신지에 대해 얘기했다. 작성자가 트윗을 삭제하면 내 글에 깨진 콘텐츠가 남는다. 제대로 동작하더라도 독자는 Twitter의 트래커를 함께 불러와야 한다. 지금까지는 트윗을 스크린샷으로 찍어 넣으며 때우고 있지만, 깔끔한 방법은 아니다.

Hugo(이 블로그에 쓰는 정적 사이트 생성기)에서 {<tweet id="12345">} 같은 숏코드로 트윗을 임베드하고, Hugo가 트윗 데이터를 가져와 소스 관리하에 저장해서 Twitter에 대한 지속적인 의존성을 없애고 싶다.

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

LGUG2Z의 솔루션을 Hugo에 맞춰 적용해 보려 했지만 너무 복잡해졌다. 독립 스크립트 하나를 작성해 Twitter에서 데이터를 다운로드하고 이를 트윗과 유사한 UI로 렌더링하도록 했다. 일반 텍스트 트윗은 그런대로 괜찮았지만, 미디어가 포함된 트윗이나 리트윗을 처리하려 하니 불안한 기반 위에 너무 많은 것을 쌓는 느낌이 들었다.

Michael Stapelberg의 Immich 사용기

예전에는 모든 사진을 Google Photos에 저장했다. 프라이버시가 걱정됐지만 Google Photos가 다른 어떤 서비스보다 훨씬 좋아서 코를 막고 그냥 모든 사진을 맡겼다. 이제는 프라이버시에 더 민감해졌고 Google을 덜 신뢰하게 되어 새 사진은 Google Photos에 올리지 않고 있지만, 대체 서비스를 아직 찾지 못했다.

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

Firefox 향상된 추적 방지 기능

Firefox가 최근 향상된 추적 방지 기능을 개선했는데, 존재 자체를 모르고 있던 기능이었다. 켜 보니 uBlock이 허용하던 트래커까지 차단하면서도 오탐은 없었다.

“부자 친구, 가난한 친구”

2022년에 나온 “부자 친구, 가난한 친구”와 몇 주 전에 올라온 후속 글을 이제야 발견했다. 친구에게 부탁하는 대신 전문가를 고용하는 부분(예를 들어 친구 대신 이사업체를 부르는 것)에 깊이 공감했다.

아마 나는 곡선에서 가장 애매한 구간에 있는 것 같다. 친구에게 이사 도와달라고 부탁하기 싫을 만큼은 여유가 있지만, 손님을 편하게 맞이할 별채를 가질 만큼 부유하지는 않은 위치 말이다.

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

Deel의 기업 스파이 이야기는 내 주변에서 놀라울 정도로 관심을 받지 못하고 있다.

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

Rippling은 11월에 업데이트를 올리며 Deel이 COO의 아내를 통해 스파이에게 돈을 송금한 은행 기록을 찾았다고 밝혔다. 공교롭게도 그 아내는 윤리 문제로 악명 높은 또 다른 기업인 Robinhood에서 컴플라이언스 책임자로 일하고 있었다.

Deel의 불만족한 전 고객으로서, 그들이 자업자득을 당하는 모습을 보니 통쾌하다.

마무리

무엇을 해냈나?

배운 점

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

다음 달 목표

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

도움이 필요한 부분

  • “프론트 페이지에 오를까?” 게임의 베타 테스트에 관심 있다면 연락해 달라.

원문은 Michael Lynch님이 에 게재했습니다.

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