dario 5.0: a major version earned by subtraction.
Most software earns a major version by adding. dario earned its 5.0 by removing: two breaking deletions that leave the codebase smaller, the mental model simpler, and the one job it does easier to audit. Here's what we cut, why a breaking change is the feature, and the discipline that makes deleting a working code path safe.
dario does one job: it makes your Claude Pro or Max subscription usable in any tool, Cursor, Cline, Aider, the Agent SDK, your own scripts, at subscription pricing instead of per-token API bills. One local endpoint, zero runtime dependencies, small enough to read in a weekend. That last property isn't a vanity metric; it's a promise. You can only trust a proxy that sits between you and your credentials if you can actually read what it does, and "readable" is a thing software loses a little of with every feature you bolt on.
So the interesting question for a 5.0 was never "what do we add." It was the opposite: what can we take away and be left with something clearer? Two things came out. Both are breaking changes. Both make the code smaller.
The pool becomes the only model
dario started single-account-first. You ran dario login, and it used one set of credentials from one file. Later, a multi-account pool arrived as an add-on: route requests across several Claude seats, fail over when one hits a rate limit, keep each conversation sticky to the account whose cache is already warm for it. Genuinely useful, and it meant the proxy now carried two credential models at once. The request handler forked on every request: the pool path, or the single-account path, re-asked across account selection, rate-limit accounting, failover, and analytics. The same either/or, about fifteen times.
v5 collapses that. The account pool is now the one model, and a plain dario login is simply a pool of one. A pool of one and a pool of many run the identical path.
before after
────────────────────────── ──────────────────────────
dario login → single path dario login → pool of one ┐
accounts add → pool path accounts add → pool of N ┘→ one path
For a solo user, this is invisible. dario login then dario proxy still just works, with no accounts add step and your credentials file left exactly where it was. What changed is underneath: one request path instead of two, one place where selection and failover live, one credential model to reason about. The pool ? … : single-account fork is gone from the hot path, and with it a whole category of "works in pool mode, subtly different in single mode" bugs, the kind that can only exist when you maintain two paths that are supposed to behave the same but drift a little every time you touch one and not the other.
Here's the part that matters more than the diff, because it's the judgment, not the code. Deleting a working code path is the scary kind of refactor, the single-account path worked, people depended on it, and removing it means betting the pool path covers every case it did. The way you make that bet safe is to prove the surviving path first. dario's pool routing, per-account headroom, sticky sessions, cascading failover across accounts on a rate limit, was already built and covered end-to-end by a routing test suite before v5 touched anything. So the unification wasn't a leap of faith. It was pointing everything at the path we'd already validated, then removing the other one. You don't earn the right to delete until the thing you're keeping is proven; that ordering is the whole trick.
Shim mode is gone
The second deletion is a transport called shim. Early on, dario had two ways to route a tool's traffic. Proxy mode is an HTTP endpoint your tool points at, the normal way. Shim mode was cleverer: inject into the tool's own process and rewrite its outbound requests in place, no separate server. Clever, and only ever half-right. Shim reshaped a subset of what a genuine Claude Code request looks like, and on the single most common request shape it quietly fell back to forwarding the tool's raw request unchanged, which is exactly the case where reshaping mattered. Proxy mode rebuilds every request to the full canonical shape and works for every non-Claude-Code client. Shim was strictly worse for the thing it was advertised to do, and it had carried a deprecation notice since 4.2.
v5 removes it. The dario shim command, its process-injection runtime, and its tests are deleted, a bit over a thousand lines of code and test gone. The command name still resolves, on purpose: run it and it prints a one-line pointer to proxy mode and exits non-zero, so a script that never migrated fails loudly instead of silently doing the half-right thing. Removing shim deletes a footgun and a maintenance surface, and it leaves exactly one answer to "how do I route my tool through dario" instead of two, one of which came with an asterisk.
Why a breaking change is the feature
A smaller surface is a promise you can keep. "Auditable in a weekend, zero runtime dependencies" gets more true when you delete paths, not less, and the only way to delete the second credential path and the half-working transport was to accept a breaking change. So we took the major-version bump not as permission to pile on, but as the one moment you're allowed to remove things people were told to rely on.
Breaking changes spend user trust, so you spend them on the right things. We spent this one on a transport that was already deprecated (shim) and on an internal unification that's invisible to the common case (the pool), and we wrote the migration so the 95% path is zero-effort: solo dario login + dario proxy users do nothing at all, and a v4 config file loads unchanged.
The one exception worth stating plainly: a multi-account user will notice one behavioral change. Each pooled account now runs its own session lifecycle independently, which is simply how each account would behave if it were its own client, rather than sharing one across the pool. A solo pool-of-one behaves exactly as the old single account did, down to the wire. If you run several seats and had come to depend on the old shared-session behavior, that's the one line in the v4 → v5 migration guide worth reading twice. Everyone else: nothing to do.
The receipts
dario 5.0.0 is live: npm install -g @askalf/dario, or the multi-arch container image. The two deletions landed as #710 (pool-as-primitive) and #707 (shim removal), integrated behind a v5 branch and shipped together so no in-between release ever half-applied a breaking change. The release itself went out the way dario's releases always go out: one merge, and the pipeline built, smoke-tested, tagged, cut the GitHub release, published to npm with provenance, and pushed the image, in a single run, no hands on the wheel.
The whole thing is still on GitHub, still zero-dependency, still small enough to read in a weekend, a little smaller than it was last week. That's the version of progress we're most interested in: not the changelog that only grows, but the one that occasionally, deliberately, shrinks.
We build and run AI systems where the path between you and the model is yours to see and tune: the proxy in the middle, the credentials you own, the cost work that decides whether something is viable or just expensive. If you're moving work off per-token billing without giving up control of the stack, that's the kind of thing we're good at.
Start a conversation →