Monorepo Setup
This guide walks you through setting up a monorepo with multiple languages managed by Bazelle.
Overview
By the end of this guide, you’ll have:
- A Bazel monorepo with Go, Kotlin, and Python
- Automatic BUILD file generation
- Shared libraries across languages
Prerequisites
- Bazel 7.0+ (or Bazelisk)
- Bazelle installed (Installation guide)
Project Structure
We’ll create this structure:
Directorymy-monorepo/
- MODULE.bazel
- BUILD.bazel
Directoryservices/
Directoryapi/ (Go service)
- main.go
Directoryauth/ (Kotlin service)
Directorysrc/main/kotlin/
- Auth.kt
Directorylibs/
Directoryutils/ (Go library)
- utils.go
Directoryml/ (Python library)
- model.py
Directoryproto/
- api.proto
Step-by-Step Setup
-
Create the project directory
Terminal window mkdir my-monorepo && cd my-monorepo -
Initialize with Bazelle
Terminal window bazelle init --name my-monorepoThis creates
MODULE.bazelandBUILD.bazelwith detected languages. -
Enable additional languages
Edit the root
BUILD.bazel:BUILD.bazel # gazelle:prefix github.com/myorg/my-monorepo# gazelle:kotlin_enabled true# gazelle:python_enabled true -
Create the Go service
Terminal window mkdir -p services/apiservices/api/main.go package mainimport ("fmt""github.com/myorg/my-monorepo/libs/utils")func main() {fmt.Println(utils.Hello("API"))} -
Create the Go library
Terminal window mkdir -p libs/utilslibs/utils/utils.go package utilsfunc Hello(name string) string {return "Hello from " + name} -
Create the Kotlin service
Terminal window mkdir -p services/auth/src/main/kotlin/com/myorg/authservices/auth/src/main/kotlin/com/myorg/auth/Auth.kt package com.myorg.authclass AuthService {fun authenticate(token: String): Boolean {return token.isNotEmpty()}} -
Create the Python library
Terminal window mkdir -p libs/mllibs/ml/model.py def predict(data: list) -> float:"""Simple prediction function."""return sum(data) / len(data) if data else 0.0 -
Generate all BUILD files
Terminal window bazelle updateBazelle will generate BUILD files for all directories:
Updating BUILD files...✓ services/api/BUILD.bazel (go_binary)✓ services/auth/BUILD.bazel (kt_jvm_library)✓ libs/utils/BUILD.bazel (go_library)✓ libs/ml/BUILD.bazel (py_library) -
Build and test
Terminal window # Build everythingbazel build //...# Run the Go servicebazel run //services/api# Test everythingbazel test //...
Generated BUILD Files
Here’s what Bazelle generates:
load("@rules_go//go:def.bzl", "go_binary")
go_binary( name = "api", srcs = ["main.go"], deps = ["//libs/utils"], visibility = ["//visibility:public"],)load("@rules_go//go:def.bzl", "go_library")
go_library( name = "utils", srcs = ["utils.go"], importpath = "github.com/myorg/my-monorepo/libs/utils", visibility = ["//visibility:public"],)load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
kt_jvm_library( name = "auth", srcs = glob(["src/main/kotlin/**/*.kt"]), visibility = ["//visibility:public"],)load("@rules_python//python:defs.bzl", "py_library")
py_library( name = "ml", srcs = ["model.py"], visibility = ["//visibility:public"],)Development Workflow
Watch Mode
During development, use watch mode to auto-update BUILD files:
bazelle watchNow when you add or modify source files, BUILD files update automatically.
Adding Dependencies
When you add a new import:
- Add the import to your source file
- Run
bazelle update(or let watch mode handle it) - Bazelle detects the dependency and adds it to
deps
Keeping BUILD Files in Sync
Before committing, verify BUILD files are up to date:
bazelle update --checkAdd this to your pre-commit hook or CI pipeline.
Next Steps
- CI/CD Integration - Add to your pipeline
- Configuration - Customize behavior with directives
- FAQ - Common questions answered