<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dan Butuc</title>
    <description>The latest articles on DEV Community by Dan Butuc (@danbutuc).</description>
    <link>https://dev.to/danbutuc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3839967%2Fedc9fd2d-f852-4a1d-a0ba-a9d461770e2c.jpeg</url>
      <title>DEV Community: Dan Butuc</title>
      <link>https://dev.to/danbutuc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danbutuc"/>
    <language>en</language>
    <item>
      <title>I Built a macOS Menu Bar App to Track Claude.ai Usage</title>
      <dc:creator>Dan Butuc</dc:creator>
      <pubDate>Mon, 23 Mar 2026 11:20:16 +0000</pubDate>
      <link>https://dev.to/danbutuc/i-built-a-macos-menu-bar-app-to-track-claudeai-usage-4fdc</link>
      <guid>https://dev.to/danbutuc/i-built-a-macos-menu-bar-app-to-track-claudeai-usage-4fdc</guid>
      <description>&lt;p&gt;I kept getting surprised by Claude's rate limits mid-conversation. I'd be deep into debugging, brainstorming, or writing — and suddenly get throttled with no warning. No countdown, no heads-up. Just... stopped.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Claude Usage Monitor&lt;/strong&gt; — a native macOS menu bar app that shows your Claude.ai usage at a glance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;The app lives in your menu bar (no Dock icon) and shows your current message count right next to a tree icon — something like &lt;code&gt;45/100&lt;/code&gt;. The icon changes colour as your usage climbs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Green&lt;/strong&gt; — plenty of messages left (under 50%)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yellow&lt;/strong&gt; — getting there (50–80%)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red&lt;/strong&gt; — almost out (over 80%)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click the icon to open a popover dashboard with a circular progress ring, a countdown to when your usage window resets, and rate limit status.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;This is where it gets interesting from an engineering perspective.&lt;/p&gt;

&lt;p&gt;The app embeds a hidden &lt;code&gt;WKWebView&lt;/code&gt; that loads &lt;code&gt;claude.ai/settings/usage&lt;/code&gt; using your stored browser session. But instead of just scraping the DOM text (which is fragile and limited), I inject a &lt;strong&gt;JavaScript fetch/XHR interceptor&lt;/strong&gt; at &lt;code&gt;document-start&lt;/code&gt; — before any page script runs.&lt;/p&gt;

&lt;p&gt;This interceptor hooks into &lt;code&gt;fetch()&lt;/code&gt; and &lt;code&gt;XMLHttpRequest.prototype.open&lt;/code&gt; to capture every API response that mentions usage, limits, or quotas. The intercepted JSON is forwarded to Swift via &lt;code&gt;WKScriptMessageHandler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why does this matter? Because the session-window rate limit data (the 5-hour window) isn't always visible in the page's DOM — it comes through API responses that the page consumes internally. The interceptor catches this data before the page even renders it.&lt;/p&gt;

&lt;p&gt;For cookie persistence, &lt;code&gt;WKWebsiteDataStore.default()&lt;/code&gt; handles everything automatically — it persists cookies to disk between app launches, so you only need to log in once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pure Swift + SwiftUI&lt;/strong&gt; — no Electron, no web frameworks, no dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WKWebView&lt;/strong&gt; for headless web interaction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript injection&lt;/strong&gt; for API response interception&lt;/li&gt;
&lt;li&gt;Ad-hoc signed &lt;code&gt;.dmg&lt;/code&gt; for easy distribution&lt;/li&gt;
&lt;li&gt;MIT licensed, fully open source&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations (Being Honest)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It scrapes Claude's usage page, so it can break when Anthropic changes their DOM or API&lt;/li&gt;
&lt;li&gt;Ad-hoc signed only (no Apple Developer ID yet) — you need to right-click → Open on first launch&lt;/li&gt;
&lt;li&gt;Currently arm64 only (Apple Silicon Macs)&lt;/li&gt;
&lt;li&gt;Auto-refresh is every 5 minutes to avoid overwhelming Claude's servers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;The app is completely free and open source:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/theDanButuc/Claude-Usage-Monitor" rel="noopener noreferrer"&gt;github.com/theDanButuc/Claude-Usage-Monitor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the &lt;code&gt;.dmg&lt;/code&gt; from the &lt;a href="https://github.com/theDanButuc/Claude-Usage-Monitor/releases" rel="noopener noreferrer"&gt;Releases page&lt;/a&gt;, or build from source with just &lt;code&gt;swiftc&lt;/code&gt; (no full Xcode required).&lt;/p&gt;

&lt;p&gt;Works with Free, Pro, Team, and Max Claude plans. Requires macOS 13 Ventura or later.&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback — what usage data would be most useful to show? I'm considering adding usage history charts and notifications when approaching limits.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this useful, a star on GitHub would mean a lot!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>swift</category>
      <category>opensource</category>
      <category>ai</category>
      <category>swiftui</category>
    </item>
  </channel>
</rss>
