Inner Source is not the goal

Inner Source often gets touted as the way to improve productivity, time to market, and many other business-oriented metrics. It helps, but it shouldn't be the goal. There are better ways.

The concept of inaccessibility and secrecy. Security systems. Inaccessible and hidden options. Secret, mystery.
Credit: iStock.com/Andrii Yalanskyi

Throughout my career, I have worked at companies that either had or wanted to have an "Inner Source" culture. For those of you who may not know what "Inner Source" is, Wikipedia's page on it is quite good.

At Amazon, most[1] of the code was viewable by anyone who had access to the code repository. Salesforce was very intentional about the Inner Source policies, ensuring that all git repositories were internally public (unless there was a really good reason not to be) and the Perforce repository was open to all who had access. There's a lot more to Inner Source than being able to view code, and this is where things can get tricky.

Let's talk through the realities of Inner Source and understand what it does and doesn't do.

Open Code

The first thing people think about (see my intro above) with Inner Source is open code. It's clear that there's a lot of value to looking at exactly how a dependency works. Functional and non-functional behaviors can be easier to identify through code than documentation[2].

Having open code is excellent. No notes.

Open Contributions

I've often seen Inner Source break down when it comes to actual code contributions across team boundaries. Oddly enough, cross-organizational contributions tend to be why Inner Source is adopted. Managers love the idea of unblocking their projects by having their own engineers do the work in other teams' systems. You know who doesn't love that? The managers who own those systems.

Open Source vs. Running Services

It should go without saying that managing an open source project and managing a running service are different beasts. Since Inner Source revolves around brining Open Source practices to a corporate environment, we should look at the differences between these two worlds.

For the purposes of this discussion, I'm going to stick to running services (typically in a SaaS environment). I haven't worked in packaged software in a very long time, so I don't have enough context.

First things first: open source contributors do not get paged for failures in their software. DevOps or ops engineers do.

The biggest blocker to open contributions comes when the team that owns the software is asked to support the contribution in a production capacity. This doesn't happen in the open source world, where all software is distributed without warranty as-is.

If I contribute to an open source project and create a performance regression, I may be asked to fix it at some point. My code may even get reverted. Any actual production impact happens a couple hops down the road, where they can downgrade the package version.

If I contribute to another team's service and create a performance regression, they're possibly getting paged and then paging me. They have a much more direct and immediate reason to block my contribution up front.

This is the crux of the issue. Engineers don't want to support code in production that they don't understand. The "just page me if it breaks" line isn't really good enough.

Contributions create technical debt

The fundamental result of frequent cross-team contributions is technical debt. An external team that needs a small tweak to behavior or an extra parameters will do the minimum to make that change in another team's software.

Repeat this process over and over, and you will find the software quickly turns to spaghetti. Owning a service or a software product means doing the right thing for all of your customers. You need to ensure the long-term viability of the software to serve the evolving needs of the business.

If another team is attempting to contribute to your service, can you really say no? You know they're just going to escalate. Are you going to be able to get them to perform part of a refactor to clean up the debt they're creating and then some? Almost certainly not. In reality, you let them commit the code and keep begging for time to stabilize your system.

There are lots of ways to build services that compensate for external contributions. You can try to be more metadata-driven, meaning the behavior changes are performed through data or configuration rather than code. You can make sure everything is pluggable, so that anything that can't be represented in configuration can be isolated and monitored. These aren't difficult concepts, so why don't we do it?

Lots of pressures prevent building new services with the right architecture. Schedules, costs, team size, and engineering talent all contribute to prototypes running in production. When we can take the small bit of extra time at the beginning to create the right abstractions, everything becomes much easier for years to come.

Open Innovation

We spent a lot of time on the contributions, so I just want to finish by talking about innovating in the open. Perhaps more important than the other pieces of the Inner Source model, ideas and designs need to be open to critique. As I've mentioned in my design review series, early feedback on ideas can remove the defensiveness that comes from pouring hours into it alone. Innovating in the open lets others see what you're doing and have input. Do you have to accept all the input? No. Absolutely not. Only a few people can have veto power over technology decisions, typically the team that owns the software, security, and legal.

All this is to say that Inner Source is good. It provides some collaboration patterns that help companies move forward. But it is a tool. It is not the goal. There is no free lunch, so take what works and ignore what doesn't. The goal is reliable, scalable, adaptable software that serves the customer needs today and tomorrow.


  1. Except for Kindle code, of course. That stuff was locked down tighter than the nuclear codes. ↩︎

  2. Documentation can get stale or just never be properly written. Very rarely will documentation be kept up to date and at the level of detail needed to identify all of these behaviors. ↩︎