Skip to main content

Shipping three open-source libraries, and knowing when one is done

00:03:39

Over a short stretch I published three open-source libraries: an MCP server for Laravel, a TypeScript agent loop, and a carrier-billing toolkit for PHP. How to publish to a registry is a solved problem and not worth writing about. What's worth writing down is the discipline that kept three small repos from being the kind of open source nobody should depend on, and the call I find genuinely hard, which is deciding when one is done.

What "not slop" meant, concretely

A repo that's safe to depend on clears a specific, unglamorous bar. Every one of the three shipped with:

  • Real tests, run in CI across the versions I claim to support. Not a token test, the actual behavior, so a contributor (including future me) gets told when they break it.
  • An honest ## Limitations section that states plainly what the library deliberately does not do.
  • No badge wall. A row of twelve shields is not a substitute for any of the above.
  • Semver tags, so "latest" means something and people can pin.
  • A verified install from the real registry before I called it released, in a clean directory, to confirm that what a user pulls down is what I think I shipped.

None of that is heroic. All of it is the line between a library and a gist someone happened to push to a package registry.

The ship loop

The actual sequence I ran for each release, and the throwaway version of each step that I refused:

  • Commit in small, logical steps, not one "did stuff" blob.
  • Gate the tests on their exit code, not on me eyeballing the output and deciding it looked fine.
  • Push deliberately, having checked I'm pushing the right repo as the right identity, not on autopilot.
  • Tag the release annotated, then watch CI all the way to green instead of assuming.
  • Install the published package from the registry and run it, because "it works in the repo" and "it works when installed" are different claims, and users only experience the second.

Every broken release I've ever seen came from someone taking the shortcut version of one of those steps.

The honest Limitations section is a feature

I've written before that for a tool an AI agent drives, the docblock admitting "this SQL check is a heuristic, not a parser" does more for safety than the check itself. The same principle scales up to the whole repo. A Limitations section that says, in so many words, "no real carrier adapters ship here, idempotency is opt-in, this does retries but not queueing" is what makes the library trustworthy. It tells a prospective user exactly where the edge is before they build on you, instead of letting them discover it in production. Stating your limits isn't underselling. It's the most useful paragraph in the README.

The hard part: knowing when to stop

This is the one I think is underrated. At some point the carrier-billing toolkit did its job. The honest assessment was: this is feature-complete for its scope, adding more would risk over-building a small toolkit into something it shouldn't be, and the next step is to publish it, not to invent a v0.5. The MCP server's roadmap explicitly parks its riskiest tools, the ones that let an agent run arbitrary code, as "probably last, if ever," rather than racing to add them because they'd be impressive.

Restraint is a senior signal precisely because every force pushes the other way. There's always another feature, another flag, another bit of surface area that would be neat. A small library that knows its scope and stops is more useful and more maintainable than one that keeps growing until it's an accidental framework. Two of these libraries, in fact, exist because I pulled a genuinely reusable core out of a larger project once it was obviously carrying its weight, which is a good test: extract what's already proven useful, rather than build a library speculatively and hope.

The compliment worth wanting

Publishing is easy. The tests, the CI, the honest limits, the verified install, that discipline is what makes a repo worth depending on. And the restraint to call a small thing finished is what keeps it worth depending on. The best compliment a little library can get isn't a star count. It's that someone read its Limitations section, understood exactly what it would and wouldn't do, built on it, and then never had to think about it again.