Written by Zach Gray
Engineering Fellow @ Bitrise
Bazel Community Expert
Founder & former CEO @ flare.build [acquired by Bitrise in 2022]
Tuist is a build tool for Xcode projects that provides declarative project generation, modularization, and build & test capabilities. In a recent surprise move, a portion of the Tuist project has been taken closed-source by the maintainers, forcing us to deprecate our Bitrise Build Cache for Tuist support.
In light of recent developments and with the interests of the mobile developer community at the forefront of our considerations, we at Bitrise feel compelled to express our concerns regarding the reliance on open-source projects that lack appropriate open-source governance. This practice may lead to unforeseen challenges in the future, particularly if a critical tool within the app release process undergoes an abrupt license modification, as exemplified by the situation with Tuist. It is imperative for every developer and organization to independently evaluate their own tolerance for such risks. For organizations & OSS contributors who share our sentiments concerning these potential hazards, we aim to shed light on this incident and initiate a discussion around possible alternatives and solutions.
Bitrise has supported Tuist on our CI platform since late 2021 when a Tuist maintainer contributed a Bitrise Step in our open-source Step Library to streamline invoking Tuist in Bitrise workflows. At Bitrise we are always happy to support any tools that make the lives of mobile developers easier, and as such have historically been supportive of this project.
Since early 2022, we’ve promoted the project to customers looking for an alternative to xcodebuild by pre-baking it into our CI images, creating blog posts promoting Tuist and directly sending traffic to the project’s docs pages. In 2023, we also began sponsoring the Tuist open-source project at the Silver level, with plans to increase our sponsorship over time.
We do not monetize any of the Tuist-specific features offered by our platform; our paying customers can use the features at no extra cost, and users on a Hobby Plan can access all of this functionality, in addition to the majority of our platform at zero cost.
An inflection point
A handful of Bitrise customers are Tuist users, even occasional contributors. We’ve worked closely with them to maximize the performance of their build & test pipelines over the past years, and a pain point we’ve heard is the lack of a readily available, easy-to-use “remote build cache”, a feature that becomes increasingly important as teams and projects grow in size. Bitrise has extensive experience solving this problem for customers using Gradle and Bazel, mature tools that more or less define the prior art for much of what Tuist does, including modularization, declarative project & build configuration, and a remote build cache client capable of storing build artifacts remotely. As a result, we recently extended Bitrise’s existing build cache server technology to support Tuist. Connecting to Bitrise Build Cache is a paid add-on for our CI customers.
When we reached out to the core Tuist project members with an offer to upstream some minor changes to the Tuist project to support connecting to remote cache using a standardized build artifact API implemented by 10 other open-source build tools, the Tuist maintainers refused to accept this change. They first cited increased maintenance overhead, but later said this would conflict with plans to monetize the project, going as far as saying this was a business decision, not a technical one. The lead maintainer made clear that an expanded Bitrise sponsorship and having Bitrise take on some of the maintenance burden was not sufficient.
Notably, our rejected diff would allow Tuist users to connect to any API-compliant remote cache server of their choice (including Bitrise, 4 other commercial offerings, and 8 fully open-source cache server backends that users can self-host). By rejecting this diff, and subsequently removing the related pieces of the codebase from OSS, the maintainers effectively guaranteed vendor lock-in for Tuist users needing a build cache.
The maintainers informed us that if we wanted to land changes upstream or extend the tool, we’d need to agree to additional legal terms & pay a recurring monthly fee–this was proposed while the codebase at the time was fully MIT licensed.
Before we were able to arrange a follow-up discussion with the Tuist maintainers, they chose to take key pieces of the project closed source, preventing users from accessing any remote cache services aside from their new commercial offering, Tuist Cloud. This effectively locks Tuist users into exclusive use of this closed-source service if they’d like to leverage a build cache, one of the most important & motivating features of Tuist, a decision other users have also commented on as less than ideal.
This episode is indicative of a deeper problem: Tuist as a (now partially) open-source project doesn’t yet have a strong & impartial governance body, and the maintainers are showing more interest in extracting revenue from their community than in making decisions that are best for the project and its end users. As of October 2023, the maintainers have removed the remote cache functionality from the open-source project without advanced notice (remarkably this presents a breaking change for our mutual users and incurs a substantial amount of effort for them to remediate rather than focusing on shipping their apps). Based on this, it is reasonable to wonder what other core functions will be unexpectedly moved behind a paywall.
For any company building Apple apps for critical parts of their business, it has already been a leap of faith to depend on Tuist (a niche tool with relatively low adoption and support), and now, in my view, we’re at an inflection point. In contrast to the current state of Tuist’s governance model, it’s useful to look at the governance of similar open-source projects that do not have the same potential issues: Gradle and Bazel.
Before we dive into Bazel, note that Gradle, the build tool used for most Android builds and tied to the commercial software Gradle Enterprise, has walked this exact line rather well, allowing users to bring their own cache if they’d like, and the same is true for Bazel (more on this below) and 9 other OSS build systems. Users of these tools benefit from multiple options, including open-source self-hostable projects, and there is no possibility of lock-in.
My personal take: Flare.build, Bazel, & Open Source
At flare.build, which I founded and was acquired by Bitrise in 2022, and at my previous venture, Scalio, we worked closely with the open-source community that sprung up around Bazel, a tool created inside Google that allows companies to build and test their code at massive scale with improved correctness and without incurring the huge associated costs caused by skyrocketing CI/CD compute resource usage. Many elements make Bazel a great project that has seen massive adoption across thousands of companies, but arguably the most important one is Google’s excellent track record of open-source stewardship and the way they engage with the community contributors and maintainers, with many core pieces of the Bazel ecosystem coming from third-party contributors from other top tech companies.
A key component of what makes Bazel so efficient is its inclusion of a remote build cache & build distribution client (and the related set of open APIs, referred to as the Remote APIs) that allows for the reducing build & test durations via any compliant caching and build distribution backend. The project itself doesn’t provide the server components, but because it adheres to the remote APIs, there is now a rich ecosystem of both open-source and commercial services available to users of Bazel (and any of the other 9 tools that implement the remote APIs). Notably, it is the commercial offerings of some contributors, like Bitrise, that enable spending time and effort contributing to the Bazel codebases; it is also worth noting that, unlike other projects, there is no conflict of interest. No contributor can make fundamental breaking changes to the Bazel project in an attempt to monetize it, because the maintainers (folks at Google, Lyft, Uber, LinkedIn & many others) wouldn’t allow it.
It’s entirely reasonable for developers working on popular & important tools to look for ways to monetize; in fact, in many cases, it’s essential to healthy and sustainable open-source software. However, when priority is given to profit at the expense of the community, this is no longer open-source software; it’s proprietary, for-profit software, complete with vendor lock-in and an uncertain future. Growing adoption due to open-source and taking contributions from the community and then moving the project to commercialized & closed-source violates the fundamental social contract between developers who contribute to open-source software (for more on this topic, have a look at this timely talk by Bryan Cantrill at the p99 Conf from Oct. 20th).
Where do we go from here?
At Bitrise, we hope that the Tuist maintainers will reverse their decision to close-source core pieces of the project. If Tuist were to rethink this strategy and move toward openness, such as joining the Mobile Native Foundation and accepting some added oversight from the MNF’s impartial steering committee, we could enthusiastically continue to recommend it as a lightweight Bazel alternative (or a stepping-stone towards Bazel for scaling teams), and we’d be able to continue to offer support for Tuist in the Bitrise Build Cache.
As the situation stands currently, we’re recommending that our customers as well as the broader development community reassess using Tuist for critical workloads and consider tools like Bazel.
The Bitrise Build Cache for Tuist will be deprecated, but for Tuist users not interested in remote build cache, the Tuist Step will continue to function & will be fully supported for the foreseeable future, barring any other unexpected changes to the Tuist project that break this functionality.
Adopting Bazel for iOS
For Tuist users looking for an escape hatch after the recent license changes, we’re working on a new open-source tool to migrate existing Tuist projects to build with Bazel with minimal effort. We’ll have an initial version of this tool available within the next few months, so stay tuned on that front; additionally, Bitrise is working closely with the iOS builds community to expand documentation and ease adoption of Bazel for mobile teams, with additional announcements detailing specific initiatives coming soon.
In the meantime, the Bazel community experts like the scalable build group at Tweag.io and others have years of experience helping organizations adopt Bazel and migrate from legacy build tools, feel free to check them out if expert Bazel support is needed.
We’re big fans of Bazel for iOS, and we think you will be too–here are a few resources to get started, regardless of whether you’re coming from Tuist or any other iOS build tooling:
Feedback from the community
We engaged with the members of the open-source community for feedback, here are some quotes we received:
- “I’d be incredibly hesitant to choose a product that locks me in to a given cache vendor that’s a product.” - anonymous
- “The open-source gRPC remote execution/caching API is an often understated benefit of Bazel. This gives organizations complete flexibility WRT which provider (or even a custom, in-house implementation) is used to power such an essential part of the build infrastructure. This means the decision about which provider to use can be made based on cost, performance, functionality, or all of the above and, generally, changed at any time. The Bazel project is wonderfully up front about all the possible services that you can use, self-service or commercial: https://bazel.build/community/remote-execution-services” - Matt Robinson