Here we go again. “The Day AppGet Died” - the short version: OSS developer fills a hole in the Windows ecosystem, Microsoft offers him a job to work on this kind of product inside the company, ghosts him, releases their competing product which appears to have borrowed heavily from his designs, doesn’t attribute original developer’s work, Internet gets mad, Microsoft gives a non-apology apology, and maybe some kind of resolution.
The moral of the story:
Another example story on why you can build either something on Microsoft ecosystem or build something popular, but never do both.— Bartosz Sypytkowski (@Horusiath) May 27, 2020
David Fowler and Damian Edwards, some of the leaders of the .NET ecosystem at Microsoft, more or less concurred:
If I had to boil it down I'd say that .NET as a platform prefers ubiquitous shared abstractions defined by Microsoft. That usually happens the moment something in the platform needs to use it.— David Fowler (@davidfowl) May 27, 2020
If you build something that enough users want to use in the .NET ecosystem, Microsoft will eventually step in and offer a first party solution because that’s what users prefer. That appears to be what’s happened with AppGet and it’s happened with ScriptCS, NHibernate, and on and on.
EDIT: After talking to David some more on Twitter following publication, it looks like I may have misunderstood his comment. He meant the abstractions used in the .NET platform, i.e. the interfaces -
HttpClient, and so on. I was talking about the default implementation Microsoft ships of those abstractions - which is what, in my view, competes with the original ideas produced in the OSS ecosystem.
I covered all of this in “The Next Decade of .NET Open Source”:
I say this as an ex-Microsoft employee, a long time Microsoft fan, and a heavy participant in the .NET OSS ecosystem: Microsoft’s product culture mandates they control everything down the stack. They’re the most risk averse company of all in the entire ecosystem, when it comes to considering third party technologies, and they will only deviate from that strategy when they realize they’re playing from behind.
David’s comment makes it pretty clear that “Not Invented Here” is an intentional strategy to make the underlying .NET runtime and platform secure. He offers some alternatives to end this viscious cycle, such as assembly-neutral interfaces - and the .NET Foundation’s “Maturity Ladder” proposal was another attempt to address this issue.
What is “the issue” - exactly?
- Popular innovations originating from the .NET OSS community are ultimately cannibalized by Microsoft due to Microsoft’s need to have an answer to every question a customer with a wallet might have;
- Microsoft ultimately practices a “one way” OSS model - you can contribute to Microsoft’s projects, but Microsoft won’t support, recommend, or depend upon third party projects even in its own ecosystem unless they achieve critical mass and Microsoft can’t afford to float an alternative (SwashBuckle, XUnit, IdentityServer, come to mind);
- As a result of issues 1-2 on this list, developers willing to take on the burden of OSS will ultimately be driven out the ecosystem and innovation will decline, leading us back to the stagnant ghetto .NET OSS was back in 2014.
It’s worth pointing out - I don’t know any individual developers who set out to create a new OSS project with the intention of building a business around it. That usually happens by accident if at all.
What most OSS developers want is for their work to be used and appreciated. Acknowledgment, attribution, and contribution are the major currencies of open source.
However, in the Microsoft ecosystem even something as trivial as attribution is scarce - because when Microsoft comes along and rips off the design of a popular third party project there’s virtually zero chance they’re going to tolerate the risk that comes with publicly acknowledging their inspirations in writing.
As Hadi Hariri, Head of Developer Advocacy at JetBrains puts it:
Hopefully people will wake up and realise that nothing has changed with Microsoft. They just spent the past few years pushing this marketing OSS pivot because they needed it for their business. It's still the same tactics, the same foul play.— Hadi Hariri (@hhariri) May 31, 2020
The New Rules for .NET Open Source
The creation of .NET Core brought about some amazing opportunities in the .NET ecosystem for innovation and creativity. Everything was new and there were opportunities to reinvent how we make world-shaping software and deliver great experiences to our own users. Microsoft was our partner in building a more creative, more open, more compatible, and more free .NET.
That era is over - if it ever existed. We are back to business as usual. If you make something popular in the ecosystem, you can expect it to become part of the platform, offered as a cloud service, built into Visual Studio, or otherwise. You will not be missed.
There’s a saying in business that if you want to displace a competitor, you need to build a product that’s at least 10x better. It’s not enough to be “just as good”. Customers will say “why should I use you, we’ve been successful with “. You need a really good reason to overcome that.
However, in the .NET ecosystem, if you’re Microsoft, that’s not generally true. If Microsoft wants to make a document database, a messaging framework, a unit test framework or a deployment automation tool, it only needs to be 1/10th as good before the conversation immediately becomes “why should we use you over the Microsoft thing?”. Microsoft become the default option, even if they’re the last to the game.
The second issue Paul highlights is much the same observation that David made: .NET users prefer 1st party solutions that come directly from Microsoft, even if they suck.
At this point you might be asking yourself: “Aaron, why don’t you just quit the .NET ecosystem, get a Fedora, grow a terrible beard or mustache, take up home brewing, and become a Go programmer already?”
Can’t do that - I look terrible in a Fedora. Also - I have a successful .NET OSS business with employees who like working here. We’re in it for the long haul. But moreover - our community, the .NET community, is responsible for building much of the software that runs the world. It’s a community worth defending and improving.
Microsoft’s central role in .NET subjects it to frequent and necessary criticism. Depleting the .NET ecosystem of innovation, whether by hiring everyone in it or driving them out of the ecosystem through cannibalism, will make .NET worse off for everyone including Microsoft in the long run.
There are three groups that make up the .NET OSS ecosystem:
- Microsoft, the creator of the platform;
- The OSS community, who builds works on top of it; and
- The users, who create value using the works of the previous two groups.
Change must come from somewhere and I have some bad news - it’s not going to be Microsoft (has no short-term economic incentive to change) or the users (Microsoft by default is fine for many of them.)
Incentives matter. It’s going to be the OSS creators who are going to have to reshape the ecosystem by changing and creating new incentives. That’s going to be done by changing the business model of .NET OSS. Here are the new rules for developing open source in the .NET ecosystem:
1 - If you’re filling an infrastructure gap with OSS: logging, configuration, build systems, package management, DI, and so on - accept that you’re going to inevitably get copied if you do it well. Price it in and don’t get mad when it happens. Thank you for your service in improving the .NET ecosystem, even if that work goes unrecognized, but now you know what’s coming.
2 - Incentivize users to care about your project and not just what the project does for them. The slow, creeping force behind the erosion of .NET OSS is a self-inflicted problem: users have no incentive to support third party OSS because Microsoft will eventually assume the costs in maintaining the technologies users use. You heard it directly from the architects who work at Microsoft.
Users need to care about your project in order for it to have a future even after Microsoft creeps into the space. How do you accomplish this?
Some examples of projects that have done this well and how they did it:
- Serilog - even after Microsoft creeped into the logging space Serilog is still an extremely popular logging library. How did they pull that off? By fully embracing what made them different and special: focusing on structured event data inside logs. That level of sophistication isn’t necessary for many users who just want basic logging - but for the developers managing complex systems this differentiator is quite important.
- Akka.NET - my project. Microsoft has now released… I think four different distributed actor system technologies since we launched our project in 2013. We’re still growing rapidly. And we grow because of what makes us different: our actors scale down to support local / device use cases, don’t require any third party infrastructure out of the box, our company Petabridge runs lots of trainings and offers hands-on support, and on top of that: lots of Scala developers who switch jobs are delighted to discover that Akka.NET supports much of the same tools, syntax, and ideas as the original Akka project does.
- Autofac - a DI container that is still immensely popular long after Microsoft entered the space. How did they survive? By making strongly typed DI easy, safe, and fun for most .NET developers. The level of documentation they have and the robustness of their technology makes it very difficult to screw up. Developers who rely on DI love Autofac because it’s one of those technologies that “just works.”
The common throughline on these projects: they survive because they’re more than their source code. Each of these projects has active communities which have intrinsic value to users. Microsoft can replace technology; they can’t so easily replace community.
3 - Take OSS sustainability seriously: build a profitable business around your project if you care about long-term viability.
So why would this help change the status quo in the .NET ecosystem? How would this make innovation sustainable long term?
The answer is simple: because you now have an economic incentive to fight for the business of your paying customers. This is why Chocolatey is going to survive the creation of
winget whereas AppGet will not: because Chocolatey supports the OSS projects’ founders and contributors livelihoods.
Moreover, breaking the cycle of OSS strip mining requires that corporate users who can afford to pay for OSS software start forming pay-for-OSS habits - and you can only do that by offering something they want.
What are some ways of doing that?
- Consider changing your licensing model - does your code do something complicated and specialized? Dual license it under an aggressive copyleft license like AGPL and require users to purchase a non-transferable, annual license for commercial use. This is what RavenDb and NServiceBus have both done successfully for years. SixLabors is now currently pursuing this for ImageSharp. If you want to get paid for your work, this is a great way to do it.
- Build a moat - can’t change your license? How about offering a managed cloud service for your project? Or proprietary add-ons targeted at big enterprises (auth, access control, and auditing are usually popular.)
4 - Think bigger.
My favorite idea from this list. It addresses an original problem sin with our ecosystem: the problems we address are often small gap-fillers. Why not try something huge and different? Look at Fable and the SAFE stack - these are bold .NET OSS projects. And even if these projects became popular on the same scale as ASP.NET I doubt Microsoft would adopt them - they don’t need to.
Microsoft’s business model is built around fast-following innovators into the greater software ecosystem. The bigger the innovation, the longer it takes for them to enter the space. Small gap-filler innovations won’t take long to integrate into the core of the platform if they’re popular.
Eventually if you are successful with a big, bold new idea Microsoft might want to follow you with their own offering. But that’s a process that will take many years - plenty enough to build a moat. Chocolatey and AppGet were big, bold ideas when they were first created years ago - now they’re commonplace as a result of their success and the success of that type of project more globally in other ecosystems.
Don’t confuse criticism of Microsoft or the .NET ecosystem for mean-spirited trolling. The .NET ecosystem is responsible for building the software that runs the world. The critics who’ve weighed in on this episode largely want to keep it that way. And this is a discussion that should never end - as it’s the only way to avoid repeating the mistakes of our past.