PyQt6에서 Tauri 2까지 — Claude Usage Widget 만들기
Claude Usage Widget은 Claude Code 사용량을 데스크톱 한구석에 띄워주는 Windows·macOS 위젯이다. 위젯 자체에 대한 기능·설치 안내는 소개 글에 정리했고, 여기서는 이걸 어떻게 시작해서 왜 두 번 만들었는지 정리해본다.
시작은 포크였다
원래는 INNO-HI/ClaudeUsageWidget이 있었다. @khwee2000님의 작업으로, macOS에선 깔끔한 네이티브 메뉴바 위젯이었지만 Windows는 로컬 Node.js 서버를 띄우고 브라우저로 접속하는 방식이었다. 데스크톱 한구석에 항상 떠 있는 위젯은 아니었다.
그래서 원작 코드를 가져다 Windows에서 데스크톱 위젯으로 쓸 수 있게 고쳐 혼자 쓰고 있었다. 쓰다 보니 같이 쓸 사람도 있겠다 싶어서, 원작자 허락을 받고 GitHub에 올렸다. 처음 공개 버전은 PyQt6로 만들었다.
PyQt6 라인 — v1.5까지
PyQt6는 Python으로 데스크톱 GUI를 빠르게 만들 수 있다는 장점이 있다. 첫 공개부터 v1.5까지 기능을 빠르게 쌓아갔다. Mini 모드, 자동 업데이트, 작업표시줄 숨김, Detail 모드, 토큰 만료 처리 안정화까지.
그런데 쓰다 보니 한계가 보였다.
- 인스톨러가 무거웠다. Python 런타임을 같이 번들해야 해서 배포 크기가 컸다.
- OS 통합이 까다로웠다. Win11의 Mica/Acrylic 백드롭이나 시스템 트레이 아이콘 같은 OS 기능을 직접 다듬는 데 손이 많이 갔다.
- 자동 업데이트도 직접 짜야 했다. 굴러가긴 했지만 매번 손이 갔다.
- 디자인 자유도가 답답했다. 위젯이 좀 더 깔끔하고 모던한 느낌이었으면 했는데, PyQt6의 네이티브 위젯으로는 한계가 있었다.
v2.0 — Tauri 2 + SolidJS + Rust로 재작성
마음에 안 드는 부분을 부분적으로 고치기보다 처음부터 다시 짜는 게 빠르겠다 싶었다. 그래서 v2.0은 스택을 완전히 갈아엎었다.
왜 Tauri 2인가
가볍다. Rust 백엔드 + 시스템 WebView 프런트엔드 조합이라 인스톨러도 작게 떨어진다. 시스템 트레이·자동 업데이트·OS 백드롭이 1급 시민으로 지원된다는 점이 컸다. PyQt6에서 직접 다듬던 것들이 그냥 된다. 웹 프런트엔드라 디자인 자유도도 훨씬 넓다.
왜 SolidJS인가
반응성 모델이 단순하고 빠르다. 위젯처럼 작은 컴포넌트가 자주 갱신되는 화면에 잘 맞는다. UnoCSS·Motion One과의 궁합도 좋아서 디자인을 다듬기 편했다.
왜 Rust인가
Tauri 2의 백엔드는 Rust다. OAuth credentials 파일 mtime 감시, 자동 업데이트 서명 검증 같은 OS-level 작업을 깔끔하게 짤 수 있다.
두 번 만들면서
PyQt6 v1 라인이 없었다면 v2.0의 디자인이나 스택 선택이 이만큼 명확하지 못했을 것이다. 한 번 만들어서 끝까지 굴려보고 한계에 부딪혀본 게 v2의 좋은 출발점이 됐다.
한계와 앞으로
개인 빌드라 인스톨러에 정식 코드 서명이 들어가 있지 않다. 첫 실행 시 Windows에선 SmartScreen, macOS에선 Gatekeeper 경고를 한 번 우회해서 실행해야 한다.
그리고 Anthropic의 OAuth 사용량 엔드포인트가 비공식이라, 정책이 바뀌면 위젯이 동작을 멈출 수 있다. 그때마다 따라잡는 게 앞으로의 유지보수 포인트가 된다.
위젯 자체에 대한 기능·설치 안내는 소개 글에 정리해두었다.