Skip to content

Migration Considerations ​

Moving to modern Bazel with Bzlmod requires careful planning and execution. This guide focuses on migrating Go, Rust, and TypeScript projects to Bazel's module system.

Migration Strategies ​

1. New Projects ​

  • Start with MODULE.bazel
  • Use modern rules
  • Follow best practices from start
  • Avoid legacy patterns

2. Existing Projects ​

  • Gradual module adoption
  • One language at a time
  • Maintain compatibility
  • Test thoroughly

Modern Setup ​

1. Module Configuration ​

python
# MODULE.bazel
module(
    name = "my_project",
    version = "0.1.0",
)

# Core dependencies
bazel_dep(name = "rules_go", version = "0.46.0")
bazel_dep(name = "gazelle", version = "0.35.0")
bazel_dep(name = "rules_rust", version = "0.40.0")
bazel_dep(name = "aspect_rules_ts", version = "2.1.0")
bazel_dep(name = "aspect_rules_js", version = "1.34.0")

# Go toolchain
go_sdk = use_extension("@rules_go//go:extension.bzl", "go_sdk")
go_sdk.download(version = "1.21.5")

# Rust toolchain
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(edition = "2021", versions = ["1.75.0"])

# TypeScript/JavaScript toolchain
npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm")
npm.npm_translate_lock(
    name = "npm",
    pnpm_lock = "//:pnpm-lock.yaml",
    verify_node_modules_ignored = "//:.npmignore",
)

2. Development Tools ​

python
# BUILD.bazel
load("@bazel_gazelle//:def.bzl", "gazelle")

gazelle(
    name = "gazelle",
    prefix = "example.com/myproject",
)

3. IDE Configuration ​

json
// .vscode/settings.json
{
    "bazel.buildFlags": ["--config=dev"],
    "bazel.enableCodeLens": true,
    "gopls.build.directoryFilters": ["-bazel-bin", "-bazel-out"],
    "rust-analyzer.linkedProjects": ["Cargo.toml"],
    "typescript.tsdk": "node_modules/typescript/lib"
}

Common Challenges ​

1. Dependency Management ​

  • Registry-based dependencies
  • Version resolution
  • Platform compatibility
  • Feature flags

2. Build Configuration ​

  • Platform settings
  • Toolchain selection
  • Build caching
  • Remote execution

3. Development Workflow ​

  • Fast iteration
  • IDE integration
  • Testing strategy
  • Debug support

Language-Specific Migration ​

Go Projects ​

  1. Initial Setup

    python
    # MODULE.bazel
    bazel_dep(name = "rules_go", version = "0.46.0")
    bazel_dep(name = "gazelle", version = "0.35.0")
    
    # Configure Go
    go_sdk = use_extension("@rules_go//go:extension.bzl", "go_sdk")
    go_sdk.download(version = "1.21.5")
  2. Migration Steps

    • Keep go.mod as source of truth
    • Use Gazelle for BUILD files
    • Update module dependencies
    • Test incrementally

Rust Projects ​

  1. Setup

    python
    # MODULE.bazel
    bazel_dep(name = "rules_rust", version = "0.40.0")
    
    # Configure Rust
    rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
    rust.toolchain(edition = "2021", versions = ["1.75.0"])
  2. Migration Steps

    • Direct crates.io integration
    • Platform-specific dependencies
    • Test configuration
    • Debug setup

TypeScript Projects ​

  1. Configuration

    python
    # MODULE.bazel
    bazel_dep(name = "aspect_rules_js", version = "1.34.0")
    bazel_dep(name = "aspect_rules_ts", version = "2.1.0")
    
    # Configure npm
    npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm")
    npm.npm_translate_lock(
        name = "npm",
        pnpm_lock = "//:pnpm-lock.yaml",
        verify_node_modules_ignored = "//:.npmignore",
    )
  2. Migration Steps

    • Use pnpm for dependencies
    • Configure TypeScript
    • Set up esbuild/SWC
    • Enable HMR

Development Workflow ​

1. Local Development ​

bash
# Go development
go test ./...
bazel test //...

# Rust development
cargo check
bazel build //...

# TypeScript development
pnpm run dev
bazel run //app:dev

2. CI/CD Pipeline ​

yaml
# .github/workflows/bazel.yml
name: CI
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build and Test
        run: |
          bazel test //...
          bazel build //... --platforms=@rules_rust//rust/platform:linux_amd64

Best Practices ​

1. Module Organization ​

  • Clear dependency boundaries
  • Consistent versioning
  • Platform compatibility
  • Feature management

2. Development Flow ​

  • Fast local iteration
  • Regular validation
  • Automated updates
  • Clear documentation

3. Testing Strategy ​

  • Unit tests with native tools
  • Integration tests with Bazel
  • Cross-platform testing
  • Performance benchmarks

Migration Checklist ​

1. Pre-Migration ​

  • [ ] Audit current dependencies
  • [ ] Plan module structure
  • [ ] Set up toolchains
  • [ ] Configure IDE support

2. During Migration ​

  • [ ] Convert to MODULE.bazel
  • [ ] Update rule versions
  • [ ] Test each component
  • [ ] Validate builds

3. Post-Migration ​

  • [ ] Remove legacy code
  • [ ] Update documentation
  • [ ] Train team
  • [ ] Monitor performance

Measuring Success ​

1. Build Metrics ​

  • Build time
  • Cache hit rate
  • Cross-platform success
  • Test coverage

2. Developer Experience ​

  • Local build time
  • IDE responsiveness
  • Debug capability
  • Team feedback

3. Code Quality ​

  • Dependency clarity
  • Build reproducibility
  • Test reliability
  • Documentation quality

Conclusion ​

Successful migration to modern Bazel requires:

  1. Clear Strategy

    • Modular approach
    • Incremental changes
    • Regular validation
    • Team alignment
  2. Technical Excellence

    • Modern tooling
    • Best practices
    • Performance focus
    • Quality assurance
  3. Team Support

    • Clear documentation
    • Regular training
    • Quick feedback
    • Continuous improvement

Remember that migration is an opportunity to improve your build system and development workflow.

Released under the MIT License.