Bazel vs Maven

Ruthreshwar Gajendiran
4 min readDec 29, 2021

Over the years, I have always used Maven or Gradle for dependency management. Why? Because it is very easy to understand and maintain Maven. I had different questions when I first learned about Bazel.

  1. Why do we need Bazel when Maven works like a charm?
  2. Bazel avoids “Dependency Hell” — We have an option to exclude a version that conflicts with other dependencies. What does Bazel do that’s simpler than this?
  3. We have centralised repositories where Maven artifacts can be stored and distributed. How do I manage external dependencies using Bazel?
  4. Maven has very minimal configuration (mostly it is only the pom.xml (Project Object Model) and project structure) but when I look at Bazel it has a lot of complex configurations. Is it really worth it to even start with Bazel?
  5. We have git submodules concept to link project to specific commit version internally. Why do we require Bazel?

Do you also feel the same way? If you have more questions, feel free to add in the comments below. I had these questions when there were talks about migrating from Maven to Bazel.

As someone who has used Maven for over ten years, Bazel was easy for me to understand when I started comparing Bazel and Maven. It became clear to me that the intent for both are different.

Let me try to explain the answers for the questions I posted above. This writeup will help you to understand what is Bazel in comparison to Maven.

Question 1: Why do we need Bazel when Maven is working like a charm?

Maven downloads all dependencies for the project, compiles the source code, performs operation like documentation and any maven plugin task and finally creates a package. It basically makes our build process smooth.

Say you have a mono repository with multiple services or multiple components. Some drawbacks of maven here is

MAVEN: Once a library in the mono repository is updated every client has to upgrade to the latest version.

Say for example in a mono repo if a project is using their service client version 1.0 and service client is introducing new changes in 1.1 all the projects using service client 1.0 has to update to 1.1 to use the new features. Few projects may decide to stick to an older version, as they don’t see any pressing need for the update.

BAZEL: It is best suited for mono repositories. Bazel doesn’t depend on generated artifacts, but it depends directly on the commit. When Bazel updates the commit all modules gets updated code.

MAVEN: Build process is slow since it takes time to download all the external dependencies. For a mono repo you may have to download all the dependencies or build the whole project if you want to test your change.

BAZEL: Bazel is smarter. In the first step, Bazel constructs a dependency graph for each step.

Each step results in an SHA hash. If the SHA changes from the previous build the subsequent dependent actions will be triggered. This way, Bazel triggers only necessary steps and this makes the process faster.

In the below image say if Application5 has few changes in this case only the Application5 and its dependencies (highlighted in yellow) will be built by Bazel.

Question 2: Bazel avoids “Dependency Hell”

With maven, we get a lot of transitive dependencies.

With Bazel we can make all the modules use the same dependency version. (You can use different versions of the same dependency in multiple modules, but Bazel strongly recommends Single Version Policy). This way once an artifact is updated in a single place, the whole repo will be referred to the updated version.

  1. Different modules use different version of same artifacts. (either because of same dependency or different version numbers in the respective pom)
  2. In step 1 Bazel recommends to use Single Version Policy. This way dependency hell problem is avoided.

Question 3: How do I manage external dependencies using Bazel

Bazel supports Maven. You can think of Bazel as a package that wraps Maven and other functionalities.

In case of Bazel all the internal dependencies are referred using the commit ID or SHA reference. External dependency can be referred using Maven. The maven repo will still be used by Bazel to download the external dependencies.

Question 4: Configuration complexity

BUILD can be considered as POM file. Bazel will automatically detect all the nested folders with BUILD file unlike Maven where we have to externally add the module to parent pom.

WORKSPACE file is like settings.xml file in Maven. It contains all the configuration details like maven dependencies, local references, Java image details etc…

All the maven dependency versions are defined in WORKSPACE file and BUILD file will just refer to the dependencies.

Question 5: What about git submodules?

Bazel is for Mono repo, whereas git submodules are used for poly repos. As mentioned earlier Bazel is a package with multiple functionalities.

You can use Bazel for poly repo too, in that case Bazel at high level acts as git submodule where the specific git version of the application will be referred directly.

Bazel also supports versioning with GIT SHA, which avoids direct dependency within internal code.

Overall, I find Bazel very much suitable for mono repos, and it addresses the pain of working on a big mono repo by taking smart decisions during build and package. This way it helps developers by saving more time during build process and helps organisation by utilising less resource.

Hope this overview of Maven vs Bazel is useful for people looking to switch!

Thanks for reading!!!

--

--