포스트

PyQt6에서 Tauri 2까지 — Claude Usage Widget 만들기

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 사용량 엔드포인트가 비공식이라, 정책이 바뀌면 위젯이 동작을 멈출 수 있다. 그때마다 따라잡는 게 앞으로의 유지보수 포인트가 된다.


위젯 자체에 대한 기능·설치 안내는 소개 글에 정리해두었다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.