사랑에 빠질 수밖에 없는 Matrix 채팅 앱, Komai
Matrix 서버 호스팅 서비스를 운영하는 etke.cc 팀이 기존 클라이언트의 한계를 극복하기 위해 데스크톱 네이티브 기반의 새로운 채팅 앱 'Komai'를 출시했습니다. 이들은 Qt/QML 기반의 nheko를 포크하여 시작했으나, 폐기된 libolm 대신 최신 matrix-rust-sdk로 핵심 암호화 엔진을 교체하는 등 대대적인 리팩토링을 진행했습니다. 특히 AI 보조 개발 도구를 활용해 복잡한 엔진 교체 작업을 빠르게 수행한 점이 주목받습니다.
Komai 소개: 당신도 사랑에 빠질 수 있는 멋진 Matrix 채팅 앱 🦁 2026년 5월 6일, Slavi Pantaleev (읽는 데 7분 소요)
저희 etke.cc에서는 생계를 위해 Matrix 서버를 호스팅하고 있습니다. 거의 10년 전, 저희는 Matrix 자가 호스팅(self-hosting)에 만족하지 못하고 matrix-docker-ansible-deploy Ansible 플레이북(현재 etke.cc SaaS의 기반)을 출시했습니다. 덕분에 시간이 지나면서 수천 명의 사용자를 위한 Matrix 자가 호스팅 문제를 해결했다고 믿습니다. 그동안 저희는 Matrix 클라이언트를 응시하며, 그것이 다르기를 바랐던 것들에도 수많은 시간을 할애했습니다. 오늘 저희는 그 간지러웠던 부분을 긁어주기 위해 직접 구축한 데스크톱 우선의 네이티브 Matrix 채팅 앱인 Komai를 소개합니다. 저희가 데스크톱에서의 Matrix 문제를 완벽히 해결할 수 있을지는 확신할 수 없지만, 이는 그에 대한 겸손한 시도입니다.
🤔 왜 또 다른 Matrix 클라이언트인가? ¶ 기존에 존재하는 것들에 만족할 수 없었기 때문입니다. 누구를 비난하려는 것은 아닙니다. Matrix 클라이언트를 만드는 것은 정말 어려운 일입니다. 프로토콜이 다루어야 할 범위가 엄청나게 넓습니다(방, 스페이스, 스레드, 읽음 확인, 상태 표시, 푸시 규칙, 홈서버의 특이사항 등). 종단간 암호화(End-to-end encryption)는 그 위에 얹어지는 구현 및 UX의 골칫거리입니다. 다중 기기 지원, 키 백업, 인증, 교차 서명, 복구 등이 있죠. 이 모든 것을 하나의 앱에 담아내면 UX 문제가 필연적으로 발생합니다. 그것은 누구도 견딜 수 없을 정도로 많은 사소하고 거슬리는 문제들(papercuts)을 만들어냅니다. Komai는 이러한 것들을 조금이나마 개선해 보려는 시도입니다.
🐱 왜 nheko로 시작했는가? ¶ 2026년에 수많은 새로운 Matrix 클라이언트가 쏟아져 나왔음에도 불구하고, 저희는 Matrix 클라이언트를 밑바닥부터 새로 작성하고 싶지 않았습니다. 저희는 네이티브 Qt/QML 기반의 Matrix 클라이언트인 nheko를 출발점으로 삼았습니다. 탄탄한 기반이었죠. 네이티브 수준의 성능(QML에 특이사항이 있긴 하지만 그럼에도 불구하고), 대부분 합리적인 기본값, 집중된 코드베이스(물론 레거시 코드도 꽤 있었지만요). 그리고 무엇보다 Electron 기반이 아니었습니다. 당초 계획은 소박했습니다. 너무 많은 것을 하지 않는 것이었습니다. 상위 프로젝트(upstream)에 몇 가지 UX 패치를 적용하고, 일부를 다시 기여하며, 조금 더 나은 nheko 빌드를 배포하는 것이었죠. 이 계획은 약 100개의 패치가 적용될 때까지 이어졌고, 저희는 여전히 더 많은 것을 원했습니다. '너무 많은 것을 하지 않겠다'는 계획은 여기서 끝이 났습니다.
🤝 왜 그냥 nheko에 기여하지 않았는가? ¶ 짧은 대답: 아이디어는 너무 많은데 느린 과정에 대한 인내심이 부족했기 때문입니다. 저희는 중대하고 때로는 논란이 될 수 있는 방식으로 사물을 변경할 수 있기를 원했습니다. 저희는 우리 운명의 주인이 되기를 원했습니다. 합리적인 부분에서는 상위 프로젝트에 기여하기도 했습니다. 예를 들어, nheko가 사용하던 Matrix 클라이언트 라이브러리인 mtxclient에는 다음과 같은 기여를 했습니다. 온라인 키 백업에서 발생하는 이중 Base64 인코딩 버그 수정, 이미지, 오디오 및 비디오 메시지에 선택적 파일 이름 필드 추가. 어쨌든 이 모든 것은 이제 의미가 없어졌습니다. 곧이어 저희는 mtxclient 사용을 중단했기 때문입니다. 이에 대해서는 잠시 후에 더 자세히 다루겠습니다.
🚢 테세우스의 배(The Ship of Theseus)의 순간 ¶ 약 100개의 패치를 적용한 후, 그 많은 패치들을 유지하면서 상위 프로젝트의 변경 사항을 계속 추적하는 일이 얻는 이점보다 커졌습니다. 판자를 충분히 많이 교체하고 나면 당신은 완전히 다른 배를 타고 항해하게 되는 것과 같습니다. 저희는 선택의 기로에 섰습니다. 갈라지는 목표를 계속 조율할 것인가, 아니면 허세를 부리지 멈추고 우리 자신만의 클라이언트를 출시할 것인가 말입니다. 저희는 독립을 선택했고 전기톱을 집어 들었습니다.
🔧 암호화 코어의 완전한 교체 ¶ 가장 중대한 변화는 UX 패치가 아니었습니다. 엔진 교체였습니다. Nheko의 Matrix 레이어는 mtxclient, libolm 및 LMDB 위에 구축되었으며, 이들은 모두 깊게 얽혀 있었습니다. 이러한 Matrix 라이브러리들은 현재 Matrix 생태계가 나아가는 방향을 따라가지 못하고 있습니다. libolm은 오래전에 폐기(deprecated)되었으며, matrix-rust-sdk로의 전환 가능성을 논의하는 오래된 nheko 이슈(Nheko-Reborn/nheko#1786)가 존재합니다. 엄청난 작업량 때문에 소규모 팀에게는 부담스럽고 기존 암호화 스택이 코드베이스 깊숙이 박혀 있기 때문에 망설이는 것은 nheko 유지보수자들로서는 당연한 일입니다. 그럼에도 불구하고 저희가 이 작업을 감당할 수 있었던 두 가지 이유가 있었습니다. 저희를 이끌어 준 AI 보조 개발. 이에 대해서는 아래에서 자세히 설명하겠습니다. matrix-rust-sdk가 이동할 만큼 충분히 성숙하고 그 가치가 있다고 판단한 것(더 나은 암호화(vodozemac), 슬라이딩 싱크(sliding sync), 최신 MSC 지원 및 활발한 개발). 그래서 며칠간의 작업 끝에 Codex가 mtxclient와 libolm을 뜯어내고 matrix-rust-sdk를 집어넣었습니다. 전환이 생각보다 훌륭하게 작동해서 저희도 놀랐습니다. 그럼에도 불구하고 여전히 아픔(어려움)은 따랐습니다. (글 하단 생략)