DEV Community

RAXXO Studios
RAXXO Studios

Posted on Originally published at raxxo.shop

The One Dependency I Refuse to Add to Any RAXXO Tool

  • One line in every new tool's setup checklist: no third-party analytics SDK, ever

  • Five shipped tools, zero tracking pixels, one shared rule

  • Saying no to a dependency is a design decision, not a delay tactic

  • The one exception I made anyway, and what it cost me to justify it

I keep a short list of things I will not add to a RAXXO tool. It is shorter than my list of things I will add, which is the point. Most engineering advice is about what to build. Almost none of it is about what to leave out, and leaving things out is where most of the actual judgment lives.

The rule at the top of that list: no third-party analytics SDK. Not Google Analytics, not a session-replay tool, not a "just for debugging" crash reporter that phones home more than it needs to. Every one of OhNine, Git Dojo, Blueprint, Statusline Builder, and Studio shipped without one, and every one of them will keep shipping without one. This is not a privacy manifesto I wrote to sound good in a blog post. It is a constraint I hit early, on the first tool, and decided to keep on purpose.

Where the rule came from

The first version of OhNine had a lightweight analytics snippet in it for about a week. I added it the way most people add these things: quickly, to answer a question I was curious about, with every intention of removing it once I had the answer. The question was simple, how many people actually open the menu bar app versus just leaving it running in the background. I got my answer in four days.

Then I looked at what the snippet actually shipped. It was not just an event ping. It was a small runtime that loaded a remote config, set cookies I had not asked for, and added weight to a menu bar app whose entire pitch was that it stays out of your way. A tool built around watching your Claude usage limits quietly, without asking anything of you, was itself now asking something of every person who installed it. That contradiction is what stuck with me, not some abstract privacy stance.

I pulled the snippet the same day and wrote the rule down somewhere I would actually see it again: before adding a dependency, ask what it costs the person using the tool, not just what it costs me to build. A dependency that adds a network call on every launch, a cookie the user never agreed to, or a permission the tool does not strictly need, fails that question immediately, no matter how useful the data would be to me.

What made it stick was noticing how easy it would have been to talk myself back into it. Four days of data is not much. The obvious next thought is "leave it running another month and the picture gets clearer." That is exactly how a temporary debugging snippet turns into a permanent dependency nobody remembers agreeing to. So the rule is not really about analytics specifically, it is about closing that door before curiosity reopens it. Once something is answering a question for me, I lose the instinct to ask whether it should still be there.

What "no" has actually meant

Saying no once is easy. Saying no five tools in a row, across a menu bar app, a terminal teacher, an installer, a free web tool, and a video pipeline, is what makes it a rule instead of a mood. Git Dojo is a terminal-first tool, so it would have been trivial to log every command a learner types and mine that for a "most confusing git command" report. I did not add that logging. Blueprint packages an install process, which is exactly the kind of tool vendors instrument to death to track activation funnels. I did not instrument it. Statusline Builder is free, which is usually where teams feel most entitled to add tracking, since nobody is paying and the data has to earn its keep somehow. It shipped clean too.

The pattern each time is the same. I ask whether I can answer my question with something I already have, before I reach for a new script tag. Server logs tell me how many times a page loads. Support messages tell me what confuses people, usually more precisely than an analytics funnel would, because a person explains their actual problem instead of me guessing from a drop-off graph. A GitHub issue count tells me what is broken. None of that requires adding a dependency to the tool itself. It requires being willing to read slower signals instead of a live dashboard.

The same question comes up with libraries, not just trackers. A UI framework that pulls in forty transitive packages to render a dropdown menu is a dependency in the exact same sense a tracking pixel is, it is code running on someone else's machine that I did not write and cannot fully vouch for. Studio and Watch both lean on a handful of small, single-purpose packages instead of one large framework, precisely so I can read the whole dependency tree in an afternoon if I ever need to. That is not possible once a project pulls in a kitchen-sink library, and losing the ability to actually know what is running is its own quiet cost, separate from whatever the library does.

This is also why the tone guide for the studio keeps coming back to restraint as a value, not just a writing style. A tool that respects the person using it in its code has an easier time sounding like it respects them in its copy too. The two are not separate decisions, they come from the same instinct. It is the same instinct behind why every RAXXO tool skips the loading spinner and why every RAXXO tool works without an account first: the fewer things a tool asks of someone before it helps them, the better it usually is.

What it actually costs me

I want to be honest about the tradeoff, because pretending there is none would be its own kind of dishonesty. Not having usage analytics means I genuinely do not know some things a normal dashboard would tell me instantly. I do not know the exact day-seven return rate for any RAXXO tool. I do not know which button in a settings panel gets clicked least. When I ship a redesign, I cannot watch a live graph to confirm it worked, I have to wait for slower signals and trust my own read of them.

That slowness is real friction. There have been features I shipped that I still am not sure anyone uses, because the fastest way to find out, an event log, is the thing I ruled out on principle. I have made peace with that gap by treating it as the actual price of the rule, not a problem to quietly solve by adding a "privacy-friendly" analytics vendor instead. Plenty of those exist now, and I have looked at a few. Most of them still add a script tag, a network call on load, and a dependency I would have to keep updated and trust with security patches forever. The label changes, the tradeoff mostly does not. It is the same math behind the performance budget every RAXXO tool has to meet before it ships: every extra script has to earn the weight it adds, and most tracking scripts never do.

There is a second cost that took longer to notice: I sometimes make a worse call in the short term because I am reasoning from fewer signals than a well-instrumented competitor would have. If two ways of laying out a settings screen both seem reasonable, an analytics dashboard would just tell me which one people actually finish faster. I do not get that shortcut. I have to sit with the uncertainty, ship the version I believe in, and wait for support messages or a GitHub thread to tell me if I got it wrong. That is slower and occasionally more embarrassing than a quick A/B test would be. I have decided I would rather be occasionally wrong and slow than routinely right and instrumented in a way that treats every visitor as a data point before they are a person.

The one exception, and how I justified it

I did add one exception, and it is worth naming because a rule that survives zero pressure is not really a rule, it is just a thing that has never been tested. The exception is error reporting, and only error reporting: if a RAXXO tool crashes, it can send me the crash trace and nothing else, no session history, no identifying data beyond what is unavoidable to reproduce the bug, no background pinging when nothing has gone wrong.

I justified it the same way I justify everything on the no list, by asking what it costs the person using the tool versus what it gives me. A crash report that only fires when something is already broken, and that exists to fix that exact class of problem faster, clears the bar in a way a general usage tracker never did. The test is not "is this data useful to me," almost anything is useful to me. The test is whether the tool needs to know less about a happy, working session than it needs to know about a broken one. If a dependency wants to know things about people who are having a completely fine experience, it does not pass.

Bottom Line

None of this makes RAXXO tools better in a way a customer can point at directly. Nobody has ever emailed to say thank you for the analytics snippet that is not there. But it is one of the few decisions I get to make once and then benefit from every single day after, because the absence compounds. Every new tool starts from the same clean baseline instead of a slowly accumulating pile of trackers that felt small individually and heavy together.

The honest version of this piece is not "I found the perfect answer to instrumentation." It is that I picked a constraint, felt its cost directly, and decided the cost was worth paying anyway. That is most of what building a one-person studio actually is: not avoiding tradeoffs, just being the one who has to live with whichever one you pick. I would rather build slower with less data than fast with a tool that quietly asks more of its users than it tells them.

Top comments (0)