Product development is not Open Source development

First published at Tuesday, 21 February 2023

Product development is not Open Source development

This is a blog article out of a series where I reflect on what I learned during funding, growing (, and selling) SaaS product companies. While I write those things down for myself, since I believe self-reflection is a crucial learning tool, I also want to share my thoughts with anybody who might be interested. I'm looking forward to your comments on any of these topics. An overview of all related topics can be found below. I have a bunch of these blog posts lined up, so you also might want to follow me if you like this one.

The most visible software development is the Open Source community and many developers (including myself) have learned work and software patterns there. I'm convinced though that those patterns differ significantly from developing a SaaS product and that you should pay attention to these differences.

My key take away is:

Be careful when changing the surface, but stay flexible on the inside.

Kore

With surface I mean everything a user of your prodcut/library/tool will be in touch with. For most Open Source projects this will mean about everything. If you consider a primarily visual tool like Wordpress (like it or not) it is not just the web user interface people are using, but the power of Wordpress stems from the thousands of plugins working with internal APIs. So the "surface" of Wordpress is not only the user interface but also all of their APIs, which basically means all code.

If you develop a library and publish it as Open Source (and I did so many times) basically every class becomes surface (or an interface) for the users of that library. Any change to any class's interface can be a backward compatibility break. This affects method signatures, return values, and (to obvious to even think about it) the language the library is written in.

Most SaaS products (Frontastic was different in some parts) "only" consist of a user interface and maybe some API, though. The surface is much more limited. And this has positive consequences for you work, which you should make use of to increase your velocity.

Anything which isn't you surface can be changed any time. And this means it can be far from "perfect" in the very beginning. I don't like the idea of "fake it, before you make it", but the idea of "experiment, and then refactor once the value is proven" probably is almost the same thing. The surface has to be well thought through, though, or you'll affront you customers.

An example

Let's take a look at an example: You are running an API SaaS product – the API is consumed by your customers. The API itself (be it GraphQL, REST, RESTful, …) has to be stable and your changes to the API should always be backward compatible. It could be an option to introduce a second version of your API at some point, but any time a customer has to migrate their code, it'll be almost the same effort for them to migrate to a competitor, so you should be very careful about this.

This means that the API should work for your customers from the very beginning and you should put a significant amnount of thoughts into how the API will be consumed, used etc. But does it matter which technologies you use to run that API? No. What storage layer you use? No. Where you host the API? No. How you scale the API? No. (German: Nein, Nein, Nein, Nein!)

But what will most developers care about most – usually exactly the (for your customer) irrelevant implementation details. Get yourself developers, technical product managers (, or consultants) which are able to view this from a API consumer point of view. And then tell your (other) developers that they will be able to change the underlying stack to what they want – later. Because that will then be unnoticed for the customer. A major benefit will also be that you get more actual usage statistics and profiles at this point, so you'll have a lot more data to understand what technologies might be optimal for your use case. For the initial setup aim for boring and versatile technology stacks.

Changing Open Source software

Unless you pay for a service, the providers of that service have no obligation to follow your requirements. This is especially true for (unpaid) Open Source development. Am I pissed from time to time when Open Source projects change their APIs for no apparent reason? Hell yes. But who am I to tell them (unless I pay for the development and maintenance)?

This means that Open Source projects can still change any of their APIs any time, but they are well aware that this might break use cases or all their users. This might also mean that their users will switch to another prject, but since Open Source maintainers don't make any money with this, this will be (mostly) fine for them.

But once developers get used to this development model they put far too much effort in finding sensible abstraction before they even validate the use case. Thinking about internal interface stability is one of the core parts of any software development course, scholarship, mentoring, and general education, while we should focus on designing surface APIs by use cases, validate them, and then refactor the internals to be suitable for the validated use-cases.

I've also talked about this in the past:

But we can, at least, do it better when developing a SaaS product:

Change rates in SaaS products

In SaaS product development I like to explicitely think about expected or acceptable change rates per surface/component/library – while change rate explicitly implies changes breaking with backward compatibility.

  • Any surface API should never be changed

  • Any surface frontend can be visually adapted, workflows can be improved, but use cases must never be removed

  • Connections to external providers/services/tools usually will change about every 2-3 years

  • Any internal component can always be changed (but within sensible reason), so probably not more than every 2 years

  • Internal code should be changed as soon as there is a possible improvement, so regularly every few weeks/months

For internal code you might want to take a look at our refactoring decision matrix.

Summary

Don't invest time into making code "beautiful" or "reusable" until its business value is proven and there is a use-case for this. This is true for any internal SaaS code. Focus on your surface, get it right, because you won't be able to change it. The surface could be an API, a web frontend or even code (SDKs, libraries). You'll loose customers if you change them.

Subscribe to updates

There are multiple ways to stay updated with new posts on my blog: