From rejected PR to 33MB: Tauri fork of Juejin AI usage tracker
The PR wasn't merged, so I made the Tauri version myself: installer cut from 100MB to 33MB
Hello everyone! Today I'm turning in an assignment that's been two months overdue.
First, the results: the Tauri version of the Juejin AI usage tracker is now independently maintained. A few releases have been published, and the macOS installer is 33MB. It matches the official Electron version in features: subscription quotas, desktop pet, and menu bar usage are all included.
This all started with an unmerged PR.
1. Origin: PR #138
Those of you who use the Juejin AI usage tracker know it's genuinely useful: it records how many tokens Claude Code, Codex, Cursor, and other AI tools burn, all locally, and even ranks who uses the most (who works overtime the most).
The only "but": the official desktop client is Electron-based. I write Rust in my day-to-day work, and I belong to the type who sees a 100MB installer and feels an itch. So in September I submitted a PR to the official repo: feat: add Tauri desktop app.
The result? Not merged.
Let me be clear: I understand the official decision; there would be maintenance costs and a different tech stack. The desktop client is a product shared across multiple platforms. To carry an extra UI framework for a community contribution means doubling the cost of building, testing, and maintaining. Nobody wants to inherit that. If I were the maintainer, I'd probably also say "Thanks, let's see" first.
But the Tauri version was already built. What to do? Maintain it myself. I'll take some time to nurture it when I can. I've been obsessed with Rust lately... there may also be pitfalls I can't fill... Just treat it as a hobby. If you're interested, come join in.
2. The cleverest part: the data layer wasn't touched at all
Before building the desktop version, I figured out one thing: the hardest 80% of this project isn't windows and buttons, it's the data layer — for over 30 AI tools, each stores its usage data in different locations and formats. The official team maintains a large set of parsers and periodically fixes them as tools update.
Would I rewrite that? No way.
So my architecture is one sentence: wrap the official core as-is as the engine, let Tauri be only the shell.
The immediate benefit: the official team recently added 6 new data sources (Deveco, TeleAgent, WPS Comate...), and on my side I just merge upstream — I didn't write a single parser, and features keep up automatically. When they fix bugs, I get the fixes for free. That's a great deal.
I have to honestly state the cost: to run the official core (which is Node), my installer embeds a Node runtime. So my Rust shell is only 10MB; the rest is mostly Node.
3. How the size was reduced bite by bite
The initial version was 44MB. This v0.3.0 got down to 33MB. The process was interesting:
First scan the directory: I laid out the build output and noticed hono's TypeScript declarations (.d.ts, which aren't read at runtime), duplicate CJS builds, yaml's browser build... all got bundled in. Stripped that layer first.
Then check the big items: the embedded Node binary was 110MB, of which 30MB was the full ICU internationalization library — a sidecar running locally that only handles date formatting. Shipping the full set of world languages for that is pure waste.
Switch to small-icu Node (English-only locale): but there's a gotcha — the code has 4 places using
en-CA/en-GBlocale for date formatting; under small ICU the format changes, and if dates change, data bucketing breaks. Luckily, inspection found all 4 spots use theformatToPartspattern (grab fields and assemble yourself), which is inherently locale-independent, so the swap worked immediately.Finally run a comparison experiment: same date, same timezone, official Node and small-icu Node produced byte-identical output; then ran 516 test cases, both sides identical. Solid.
Current size composition: Node runtime 81MB (the bulk after compression), Rust shell 10MB, the rest is the official core and panel. The official Electron installer is usually 100MB+ — mine is roughly a third.
The remaining roadmap is set: next steps are to rewrite the local API and storage layer in Rust (0.4.x), then gradually migrate parsers over. Full Rust implementation will be 1.0, and then the installer should target under 15MB.
4. Features now available
- 📊 Full dashboard: same dashboard as official (same data package under the hood, what you see is what you get)
- 💳 Subscription quota cards: remaining quotas for 12 channels including Claude / Codex / Cursor / Grok / Kimi / Qoder, shown right on the panel
- 🐱 Desktop pet: three built-in plus an online community pet directory; they run and jump, and bubble up token deltas after syncing
- 📈 macOS menu bar real-time usage: today's token and cost stay in the menu bar
- 🔗 Juejin login deep link: after logging in in browser, jumps back to the app automatically
- 🔄 Auto-update: with signature verification; pushes updates and upgrades in-app
- ⚙️ Auto-start on boot, silent start, theme follows system, tray resident... all the usual bits.
5. How to use
- Download: https://github.com/you-want/juejin-usage-tauri/releases
- macOS: download the
.dmgfor your chip, drag into Applications. It will be blocked the first time (I didn't buy Apple's signing service — $99/year, and the community version isn't spending that yet). Run one command in terminal to allow it, or allow it from System Settings.
sudo xattr -dr com.apple.quarantine /Applications/Juejin\ Usage.app
- Windows: download
-setup.exe, click "More info → Run anyway" on the SmartScreen prompt. - Data is fully interoperable with the official version (same data directory, same cloud sync protocol), so you can switch seamlessly.
6. In closing
Thanks again to the maintainers of juejin-cn/juejin-usage — @ATQQ and all contributors. The data foundation is built brick by brick by them. My project is essentially "adding a Rust decoration on top of someone else's foundation." Every merge upstream is me taking advantage of their work, and I'm genuinely grateful.
The two projects are complementary: the official Electron version continues to go deep, and the Tauri community edition serves those who like lightweight clients, tracking upstream long-term. If the official team ever has interest in a Rust data layer, I can bring all that I've accumulated back.
If you find it useful, go give a star at the new repo, file issues if you have problems, or just chat in the comments.
Top 1 from juejin.cn, machine-translated. The original thread is authoritative.
Still very glad to see this project receiving attention.