There is a saying that probably every Dutch parent has once said to their child:
"Als iedereen in de sloot springt, spring je er dan achteraan?"
Freely translated to the English equivalent: "If everyone jumps off a bridge, would you jump after them?" It encourages them to think for themselves rather than blindly follow something everyone else does. Still, if a large majority does something one way, there must be some advantages to following them, right? Let's discover that based on the story of how we at Moxio went for open source as a strategic choice a few years ago.
Once upon a time, in a universe not so far away...
Large parts of this framework layer were written over 10 years ago, in a time where quality re-usable and modular components were not as readily as available as today. Frameworks like Symfony2 and Angular were still under development, but the philosophies on which they were based already started to gain traction. We were skillful enough to build our own framework on these ideas and trends, so we did. Package managers like Composer and NPM did not exist yet; rather our applications were stiched together using SVN externals. This made it even more difficult to pull in 3rd party code rather than write our own.
Our in-house framework served us well over the years, and contains some really cool and nifty features. Still, over time maintaining so much generic code ourselves became more of a burden rather than a competitive advantage. Customers choose us for the insights we provide them in their data, for the usability of our applications, for the way we work together to find sustainable solutions for their problems. They don't choose us for the fully automated side effect cleanup logic in our widget framework, how awesome it may be. Moreover, having this stuff built in-house makes it more difficult to onboard new developers. They have to learn our own way of doing things (instead of already being familiar with an open source framework) before becoming fully productive, we have to maintain all documentation and tooling ourselves, IDE's have no support for our own DSL's and searching on StackOverflow will probably not show many results.
This is why roughly three years ago we made the strategic decision to move towards 3rd party open source components for our generic needs. We started shedding parts of our codebase that were not essential to our way of working and replaced them by open source solutions. We replaced parts of our serverside framework by Symfony components, introduced 3rd party tooling to make our lives easier, and are transitioning from our own widget framework to React. We're also moving from our own database abstraction layer to Doctrine's DBAL and from a proprietary command/query-protocol to GraphQL. On an infrastructure level, we're replacing more and more of our own Puppet manifests by modules from the Puppet Forge.
Moving to open source is not just a matter of replacing code; it is also a change of mindset. Right now, when encountering a problem/need, our first course of action is to investigate how others in the ecosystem approach it. Of course we discuss whether the preferred solution in the outside world matches our own vision, don't blindly follow others. Still, in a lot of cases it is way more preferable to be in a situation many other people have thought about than having problems no one else has ever encountered. Choosing solutions that are broadly used also helps to enlarge the pool of potential hires that can get up to speed in a codebase quickly.
We try not to just use open source, but to be an active participant in the surrounding ecosystem. If we encounter a bug in a third party library or find that it lacks a feature we'd like to have, we try to scratch our own itch, fix the bug or implement the feature, and contribute it back upstream. For example, our own database layer has some abstractions for SQL syntax differences between MySQL and SQLite that aren't in the Doctrine DBAL yet. We're currently trying to extend those to other database vendors and open PR's to get them included in DBAL. Apart from that, we also try to share our knowledge with the community through blogging, and release parts of our own codebase as open source (more on that in a bit). Not only does this serve the ecosystem, we as a company benefit as well. Our developers can broaden their views and keep an eye on trends in the outside world, and involvement in open source as a company can gain us some nice visibility.
Of course, switching to more open source hasn't been all fun and games. We've had our share of code breaking due to accidental BC breaks in external libraries, difficult upgrade paths to new major versions, and packages ending up unmaintained. Also, implementing a feature or fixing a bug in a codebase you're unfamiliar with can be a real challenge, although working in a new codebase can also learn you a thing or two and is a useful skill to possess. When making such a change has succeeded, another difficult aspect can be the time until that change is merged and released upstream. This requires one to either live with the bug/without the feature or to maintain a fork in the meantime. I think we're still discovering the best way to deal with that.
Releasing our own
When embracing open source in our codebase, there were some parts for which it was easy to find a suitable replacement. Sometimes there just exists a quality, well-maintained and full-featured package that can even be considered a de facto standard. For other generic concerns there wasn't an open source implementation yet, or the existing package was badly maintained or based on principles incompatible with our own views. In those cases we aim to make our own solution available as open source. We identified around 25 such modules in our codebase that were generic enough to be useful to the community and (in our view) not yet sufficiently covered by existing packages.
Detaching those from the rest of our codebase, making them slightly more generic and adding sufficient documentation takes time, so we knew that we couldn't release all those 25 components at once. To ensure that we provide maximum value to the community, we decided to send out a questionnaire to ask which of those components others could use. We also estimated the approximate amount of effort required to make each of those components suitable for release within our development team. Calculating a score of 'times requested' divided by 'required effort' then gave us a guideline for prioriting each of them, in the sense of how we could delive the most value fastest.
We're still in the process of working through that list, trying to schedule time alongside other work to release a new open source package every once in a while. All our existing releases to date can be found on GitHub. Also, feel free to still send in a response to our questionnaire. If we see a lot of requests for a component not yet released we can adjust priorities to take that into account.
Coming back to the start of this post, if everyone jumps off a bridge, would you jump after them? Well, not blindly, but if so many people jump off the bridge there have to be some advantages to it (obligatory XKCD):
- Some clever people will have probably though about the best ways of jumping off a bridge.
- There must be a lot of information about jumping off bridges on StackOverflow and blogs.
- There's probably some handy tooling and IDE support for jumping off a bridge.
- And there are definitely a lot of developers for hire that are already familiar with jumping off bridges.
So far, we feel that our choice of adopting more popular open source solutions rather than rolling our own has made it easier to grow our team and company. We're happy to have jumped off some of those bridges!