# Paid For, Then Published: How We Release Open Source

> Most of the open source we release starts as a feature a client project needed and paid for. We ship it in small, frequent releases under semantic versioning, so older projects stay on the version they were built on and upgrade when they choose. Why that works, and where it bends.

By Shibin Das · Engineering · Published 27 Oct 2026. Source: https://www.d34dman.com/posts/engineering/paid-for-then-published/
Tags: open-source, semantic-versioning, releases, maintenance, engineering, agency

If you look at the release page of one of our open source projects, it can look restless: a new minor every few days, sometimes two in a week. That isn't indecision. It is what a release looks like when the work behind it is funded by real projects, one feature at a time.

This post is about that strategy: where the work comes from, why we release it in small pieces, and how semantic versioning lets a project from three months ago keep running on the version it was built on.

---

## Funded before it is free

Most of what we publish as open source is not written for open source first. It is written because a client project needs it. A project needs a new kind of field, an extra step in an editor, an integration with something they already run. We build it, the project pays for it as part of its normal work, and it goes into production there.

Then it gets released.

That order matters to me for two reasons.

**The work is paid for.** Open source that depends on someone's spare evenings stalls when the evenings run out. Here the funding question is answered before the first line is written, because the feature is part of a project with a budget and a deadline.

**What reaches open source is not theory.** By the time a feature is in a release, it has met real content, real editors and real data. It has had its first bug reports from people who were trying to get their job done, not from people trying it out. The design decisions in it were made against an actual need, not against what we imagined someone might want one day.

The cost is that the roadmap follows the projects. Something nobody needs right now waits, however nice it would be. I think that is a fair price: it keeps us from building features for an imaginary user.

---

## One topic per release

When a project needs a feature, it needs it now, not in the next big release three months away. So we release when the feature is ready, and we keep each release about one thing.

A typical minor release adds one feature, or one coherent group of changes around one topic. Fixes go out as patch releases as soon as they are done. The result is many small releases instead of a few large ones.

That is the "restless" release page. Each entry is one project getting one thing it asked for.

---

## Semantic versioning is the contract

Releasing often is only safe if the version number tells the truth. We follow [semantic versioning](https://semver.org/):

- **Patch** (`2.4.1` → `2.4.2`): fixes only. Nothing you rely on changes.
- **Minor** (`2.4.x` → `2.5.0`): new things, added in a way that does not break what was there.
- **Major** (`2.x` → `3.0.0`): something you rely on changes, and the release notes tell you what to do about it.

That contract is what makes old projects work. A project built two or three months ago was built on, say, version 2. It requires `^2.0` and keeps receiving fixes and compatible improvements without anyone touching it. It does not have to follow every new idea we had since. When that client has the budget and the reason to move to a new major, they move, on their own schedule.

So the newest project gets the newest features the day they ship, and the older projects get stability. Both come from the same release stream.

---

## Small releases, small blast radius

The other reason to keep releases small is what happens when something goes wrong.

If a minor release contains one feature and a regression shows up, there is one place to look. The release notes are short enough to read. Rolling back means going back one small step, not giving up three months of other work to get rid of one bug.

A big release that bundles twenty changes turns every regression into an investigation. Which of the twenty did it? Can we roll back without losing the fix that another project is waiting for? Small releases make those questions mostly go away.

It also changes how upgrades feel. Moving from one minor to the next is a small, readable change, so people actually do it, instead of letting the gap grow until upgrading becomes a project of its own.

---

## Where it bends

This is the strategy as we aim for it. In practice there are a few places where it needs care, and I would rather say so.

**Not every feature is small.** Some work does not fit into one tidy minor: a new subsystem, a rework of how something is stored. For those we publish alpha and beta releases first. The project that needs the feature runs the pre-release, and the stable release comes once it has held up there. The release is still big, but its risk was taken by one project that asked for it, not by everyone who updates.

**"Stay on your version" means your major, not your exact version.** Pinning to one exact release and never moving is not safe. Security fixes and bug fixes land as patch and minor releases, and a project that never takes them will eventually run something with a known problem. The promise is: stay on the major you were built on, keep taking its updates, and you will not be broken.

**Old majors get fixes, for a while.** When a new major comes out, important fixes are backported to the previous one, so projects still on it are not left alone. That support is not forever. At some point an old major stops getting releases, and moving up becomes part of the next piece of paid work for that project.

**Patch means fix, even when it is tempting.** When a project waits for a small feature, it is tempting to slip it into a patch release. That breaks the contract quietly, so it needs discipline, and review that asks "is this really only a fix?"

---

## Why I like it

None of this is new. Semantic versioning, small releases and backports are old ideas. What I like is how they fit together with the way the work is funded:

- Client projects pay for the features, so the open source work has a budget.
- Features ship small and often, so each project gets what it needs when it needs it.
- Semantic versioning lets every older project stay put until it chooses to move.
- Small releases keep regressions small and easy to trace.

And the open source that comes out of it is code that has already done its job somewhere. That, more than anything, is what I want people to get when they install something we published.
