> ## Documentation Index
> Fetch the complete documentation index at: https://bazel-pr-30702.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration tool

***

## title: 'Bzlmod Migration Tool'

[migration_script]: https://github.com/bazelbuild/bazel-central-registry/blob/main/tools/migrate_to_bzlmod.py

[gemini_cli_setup]: https://github.com/bazelbuild/bazel-central-registry/tree/main/tools/code-agent

To simplify the often complex process of moving from `WORKSPACE` to Bzlmod, it's
highly recommended to use the [migration script][migration_script]. This helper
tool automates many of the steps involved in migrating your external dependency
management system.

**Note**: If you want to try out the AI driven Bzlmod migration, check [Bzlmod Migration Agent Setup][gemini_cli_setup].

<h2 id="migration-tool-core-functionality">
  Core Functionality
</h2>

The script's primary functions are:

* **Collecting dependency information:** Analyzing your project's `WORKSPACE`
  file to identify external repositories used by specified build targets,
  using Bazel's
  [experimental\_repository\_resolved\_file](https://bazel.build/versions/8.2.0/reference/command-line-reference#flag--experimental_repository_resolved_file)
  flag to generate a resolved dependencies file containing this information.
* **Identifying direct dependencies:** Using `bazel query` to determine which
  repositories are direct dependencies for the specified targets.
* **Migrating to Bzlmod:** Translating relevant `WORKSPACE` dependencies into
  their Bzlmod equivalents. This is a two-step process:
  1. Introduce all identified direct dependencies to the
     `MODULE.bazel` file.
  2. Build specified targets with Bzlmod enabled, then
     iteratively identify and fix recognizable errors. This step is
     needed since some dependencies might be missing in the first step.
* **Generating a migration report:** Creating a `migration_info.md` file that
  documents the migration process. This report includes a list of direct
  dependencies, the generated Bzlmod declarations, and any manual steps that
  may be required to complete the migration.

The migration tool supports:

* Dependencies available in the Bazel Central Registry
* User-defined custom repository rules
* Package manager dependencies
  * Maven
  * Go
  * Python

**Important Notes**:

* The migration tool is a best-effort utility. Always double-check its
  recommendations for correctness.
* Use the migration tool with Bazel 7 (not supported with Bazel 8).

<h2 id="migration-tool-how-to-use">
  How to Use the Migration Tool
</h2>

Before you begin:

* Upgrade to the latest Bazel 7 release, which provides robust support for
  both WORKSPACE and Bzlmod.
* Verify the following command runs successfully for your project's main build
  targets:

  ```shell theme={null}
  bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
  ```

<h3 id="migration-script-command">
  Command for running the script
</h3>

Once the prerequisites are met, run the following commands to use the migration
tool:

<pre class="prettyprint lang-shell" style={{fontSize: "12px"}}>
  # Clone the Bazel Central Registry repository

  git clone [https://github.com/bazelbuild/bazel-central-registry.git](https://github.com/bazelbuild/bazel-central-registry.git)
  cd bazel-central-registry

  # Build the migration tool

  bazel build //tools:migrate\_to\_bzlmod

  # Create a convenient alias for the tool

  alias migrate2bzlmod=\$(realpath ./bazel-bin/tools/migrate\_to\_bzlmod)

  # Navigate to your project's root directory and run the tool

  cd \<your project root>
  migrate2bzlmod -t \<targets>
</pre>

<h3 id="migration-script-files">
  Files generated by this script
</h3>

* `MODULE.bazel` - The central manifest file for Bzlmod, which declares the
  project's metadata and its direct dependencies on other Bazel modules.
* `migration_info.md` - A file providing step-by-step instructions on how the
  migration tool was executed, designed to assist in the manual completion of
  the migration process, if necessary.
* `resolved_deps.py` - Contains a comprehensive list of the project's external
  dependencies, generated by analyzing the project's `WORKSPACE` file, serving
  as a reference during the transition.
* `query_direct_deps` - Contains migration-relevant information regarding the
  utilized targets, obtained by invoking Bazel with `--output=build` on the
  project's `WORKSPACE` file. This file is primarily consumed by the migration
  script.
* `extension_for_XXX` - A file containing a module extension
  definition. The migration tool generates these files for dependencies that
  are not standard Bazel modules but can be managed using Bzlmod's [module extensions](/external/extension).

<h3 id="migration-script-flags">
  Flags
</h3>

Flags available in this migration scripts are:

* `--t`/`--target`: Targets to migrate. This flag is repeatable, and the
  targets are accumulated.
* `--i`/`--initial`: Deletes `MODULE.bazel`, `resolved_deps.py`,
  `migration_info.md` files and starts from scratch - Detect direct
  dependencies, introduce them in MODULE.bazel and rerun generation of
  resolved dependencies.

<h3 id="post-migration-cleanup">
  Post-migration cleanup
</h3>

* Delete `migration_info.md`, `resolved_deps.py` and `query_direct_deps`.
* Clean up comments from `MODULE.bazel` file which were used for the
  migration, such as `# -- bazel_dep definitions -- #`.

<h2 id="migration-tool-example">
  Migration Example
</h2>

To see the migration script in action, consider the following scenario when
Python, Maven and Go dependencies are declared in `WORKSPACE` file.

<details>
  <summary style={{padding: "16px"}}>
    Click here to see `WORKSPACE` file
  </summary>

  ```python theme={null}
  workspace(name="example")

  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  load(":my_custom_macro.bzl", "my_custom_macro")

  http_archive(
      name = "rules_cc",
      sha256 = "b8b918a85f9144c01f6cfe0f45e4f2838c7413961a8ff23bc0c6cdf8bb07a3b6",
      strip_prefix = "rules_cc-0.1.5",
      urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.5/rules_cc-0.1.5.tar.gz"],
  )

  # Module dependency
  # -------------------
  http_archive(
      name = "rules_shell",
      sha256 = "3e114424a5c7e4fd43e0133cc6ecdfe54e45ae8affa14fadd839f29901424043",
      strip_prefix = "rules_shell-0.4.0",
      url = "https://github.com/bazelbuild/rules_shell/releases/download/v0.4.0/rules_shell-v0.4.0.tar.gz",
  )

  # Repo rule
  # -------------------
  http_archive(
      name = "com_github_cockroachdb_cockroach",
      sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502",
      strip_prefix = "cockroach-22.1.6",
      url = "https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz",
  )

  # Module extension
  # -------------------
  # Macro which invokes repository_rule
  my_custom_macro(
      name = "my_custom_repo",
  )

  # Go dependencies
  # -------------------
  http_archive(
      name = "io_bazel_rules_go",
      integrity = "sha256-M6zErg9wUC20uJPJ/B3Xqb+ZjCPn/yxFF3QdQEmpdvg=",
      urls = [
          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip",
          "https://github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip",
      ],
  )

  http_archive(
      name = "bazel_gazelle",
      integrity = "sha256-12v3pg/YsFBEQJDfooN6Tq+YKeEWVhjuNdzspcvfWNU=",
      urls = [
          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz",
          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz",
      ],
  )

  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

  go_rules_dependencies()
  go_register_toolchains(version = "1.23.1")
  gazelle_dependencies()

  go_repository(
      name = "org_golang_x_net",
      importpath = "golang.org/x/net",
      sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=",
      version = "v0.0.0-20190311183353-d8887717615a",
      build_file_proto_mode = "disable",
      build_naming_convention = "import",
  )

  # Python dependencies
  # -------------------
  http_archive(
      name = "rules_python",
      integrity = "sha256-qDdnnxOC8mlowe5vg5x9r5B5qlMSgGmh8oFd7KpjcwQ=",
      strip_prefix = "rules_python-1.4.0",
      url = "https://github.com/bazelbuild/rules_python/releases/download/1.4.0/rules_python-1.4.0.tar.gz",
  )

  load("@rules_python//python:repositories.bzl", "py_repositories")
  py_repositories()

  load("@rules_python//python:pip.bzl", "pip_parse")
  pip_parse(
     name = "my_python_deps",
     requirements_lock = "@example//:requirements_lock.txt",
  )

  load("@my_python_deps//:requirements.bzl", "install_deps")
  install_deps()

  load("@rules_python//python:repositories.bzl", "python_register_toolchains")
  python_register_toolchains(
      name = "python_3_11",
      python_version = "3.11",
  )

  # Maven dependencies
  # __________________

  RULES_JVM_EXTERNAL_TAG = "4.5"
  RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6"

  http_archive(
      name = "rules_jvm_external",
      strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
      sha256 = RULES_JVM_EXTERNAL_SHA,
      url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
  )

  load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
  rules_jvm_external_deps()
  load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
  rules_jvm_external_setup()

  load("@rules_jvm_external//:defs.bzl", "maven_install")
  maven_install(
      name = "px_deps",
      artifacts = [
          "org.antlr:antlr4:4.11.1",
      ],
      repositories = [
          "https://repo1.maven.org/maven2",
      ],
  )
  ```
</details>

Moreover, to demonstrate usage of module extension, custom macro is invoked from
`WORKSPACE` and it is defined in `my_custom_macro.bzl`.

<details>
  <summary style={{padding: "16px"}}>
    Click here to see `my_custom_macro.bzl` file
  </summary>

  ```python theme={null}
  """Repo rule and macro used for testing"""

  def _test_repo_rule_impl(repository_ctx):
      repository_ctx.file(
          "BUILD",
          content = """
  genrule(
      name = "foo",
      outs = ["rule_name.out"],
      cmd = "touch $@",
      visibility = ["//visibility:public"],
  )
  """
      )

  _test_repo_rule = repository_rule(
      implementation = _test_repo_rule_impl,
  )

  def my_custom_macro(name):
      _test_repo_rule(name = name)
  ```
</details>

The end goal is to have `MODULE.bazel` file and delete the `WORKSPACE` file,
without impacting the user experience.

The first step is to follow [How to Use the Migration Tool](#migration-tool-how-to-use), which mostly is checking the bazel version
(it must be Bazel 7) and adding an alias to the migration script.

Then, running `migrate2bzlmod -t=//...` outputs:

<pre style={{fontSize: "12px"}}>
  bazel 7.6.1

  Generating ./resolved\_deps.py file - It might take a while...

  <span style={{color: "green"}}>RESOLVED:</span> <code>rules\_java</code> has been introduced as a Bazel module.
  <span style={{color: "green"}}>RESOLVED:</span> <code>bazel\_gazelle</code> has been introduced as a Bazel module.
  <span style={{color: "green"}}>RESOLVED:</span> <code>io\_bazel\_rules\_go</code> has been introduced as a Bazel module.
  <span style={{color: "green"}}>RESOLVED:</span> <code>rules\_python</code> has been introduced as a Bazel module.
  <span style={{color: "orange"}}>IMPORTANT:</span> 3.11 is used as a default python version. If you need a different version, please change it manually and then rerun the migration tool.
  <span style={{color: "green"}}>RESOLVED:</span> <code>my\_python\_deps</code> has been introduced as python extension.
  <span style={{color: "green"}}>RESOLVED:</span> <code>org\_golang\_x\_net</code> has been introduced as go extension.
  <span style={{color: "green"}}>RESOLVED:</span> <code>rules\_jvm\_external</code> has been introduced as a Bazel module.
  <span style={{color: "green"}}>RESOLVED:</span> <code>org.antlr</code> has been introduced as maven extension.
  <span style={{color: "green"}}>RESOLVED:</span> <code>rules\_shell</code> has been introduced as a Bazel module.

  Congratulations! All external repositories needed for building //... are available with Bzlmod!
  <span style={{color: "orange"}}>IMPORTANT:</span> Fix potential build time issues by running the following command:
  <span style={{fontWeight: "700"}}>bazel build --enable\_bzlmod --noenable\_workspace //...</span>

  <span style={{color: "orange"}}>IMPORTANT:</span> <code>For details about the migration process, check `migration_info.md` file.</code>
</pre>

which gives the following important information:

* Generates `./resolved_deps.py` file, which contains info about all external
  repositories declared and loaded using your `WORKSPACE` file.
* `RESOLVED` keyword describes all dependencies which are resolved by the tool
  and added to the `MODULE.bazel` file.
* `IMPORTANT` keyword describes significant information worth investing time.
* All dependencies have been resolved in this example, at least with
  `--nobuild` flag.
* It is important to run the full build (command specified) and manually fix
  potential errors (e.g. toolchain not registered correctly).
* `migration_info.md` file contains details about the migration. Check details
  [at this section](#migration-tool-report-generation).

<h3 id="migration-tool-transformations">
  Transformations
</h3>

This section illustrates the migration of code from the `WORKSPACE` file to
`MODULE.bazel`.

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Bazel Module</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      http\_archive(
      name = "rules\_shell",
      sha256 = "3e114424a5c7e4fd43e0133cc6ecdfe54e45ae8affa14fadd839f29901424043",
      strip\_prefix = "rules\_shell-0.4.0",
      url = "[https://github.com/bazelbuild/rules\_shell/releases/download/v0.4.0/rules\_shell-v0.4.0.tar.gz](https://github.com/bazelbuild/rules_shell/releases/download/v0.4.0/rules_shell-v0.4.0.tar.gz)",
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Bazel Module</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      bazel\_dep(name = "rules\_shell", version = "0.6.1")
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Go Extension</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      http\_archive(
      name = "io\_bazel\_rules\_go",
      integrity = "sha256-M6zErg9wUC20uJPJ/B3Xqb+ZjCPn/yxFF3QdQEmpdvg=",
      urls = \[
      "[https://mirror.bazel.build/github.com/bazelbuild/rules\_go/releases/download/v0.48.0/rules\_go-v0.48.0.zip](https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip)",
      "[https://github.com/bazelbuild/rules\_go/releases/download/v0.48.0/rules\_go-v0.48.0.zip](https://github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip)",
      ],
      )
      http\_archive(
      name = "bazel\_gazelle",
      integrity = "sha256-12v3pg/YsFBEQJDfooN6Tq+YKeEWVhjuNdzspcvfWNU=",
      urls = \[
      "[https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz](https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz)",
      "[https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz](https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz)",
      ],
      )

      load("@io\_bazel\_rules\_go//go:deps.bzl", "go\_register\_toolchains", "go\_rules\_dependencies")
      load("@bazel\_gazelle//:deps.bzl", "gazelle\_dependencies", "go\_repository")

      go\_rules\_dependencies()
      go\_register\_toolchains(version = "1.23.1")
      gazelle\_dependencies()

      go\_repository(
      name = "org\_golang\_x\_net",
      importpath = "golang.org/x/net",
      sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=",
      version = "v0.0.0-20190311183353-d8887717615a",
      build\_file\_proto\_mode = "disable",
      build\_naming\_convention = "import",
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Go Extension</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      go\_deps = use\_extension("@bazel\_gazelle//:extensions.bzl", "go\_deps")
      go\_sdk = use\_extension("@io\_bazel\_rules\_go//go:extensions.bzl", "go\_sdk")

      go\_deps.from\_file(go\_mod = "//:go.mod")
      use\_repo(go\_deps, "org\_golang\_x\_net")
      go\_sdk.from\_file(go\_mod = "//:go.mod")

      go\_deps.gazelle\_override(
      path = "golang.org/x/net",
      directives = \[
      "gazelle:proto disable",
      "gazelle:go\_naming\_convention import",
      ],
      )
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Python Extension</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      http\_archive(
      name = "rules\_python",
      integrity = "sha256-qDdnnxOC8mlowe5vg5x9r5B5qlMSgGmh8oFd7KpjcwQ=",
      strip\_prefix = "rules\_python-1.4.0",
      url = "[https://github.com/bazelbuild/rules\_python/releases/download/1.4.0/rules\_python-1.4.0.tar.gz](https://github.com/bazelbuild/rules_python/releases/download/1.4.0/rules_python-1.4.0.tar.gz)",
      )

      load("@rules\_python//python:repositories.bzl", "py\_repositories")
      py\_repositories()

      load("@rules\_python//python:pip.bzl", "pip\_parse")
      pip\_parse(
      name = "my\_python\_deps",
      requirements\_lock = "@example//:requirements\_lock.txt",
      )

      load("@my\_python\_deps//:requirements.bzl", "install\_deps")
      install\_deps()

      load("@rules\_python//python:repositories.bzl", "python\_register\_toolchains")
      python\_register\_toolchains(
      name = "python\_3\_11",
      python\_version = "3.11",
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Python Extension</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      pip = use\_extension("@rules\_python//python/extensions:pip.bzl", "pip")
      pip.parse(
      hub\_name = "my\_python\_deps",
      python\_version = "3.11",
      requirements\_lock = "//:requirements\_lock.txt",
      )
      use\_repo(pip, "my\_python\_deps")

      python = use\_extension("@rules\_python//python/extensions:python.bzl", "python")
      python.defaults(python\_version = "3.11")
      python.toolchain(python\_version = "3.11")
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Maven Extension</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      RULES\_JVM\_EXTERNAL\_TAG = "4.5"
      RULES\_JVM\_EXTERNAL\_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6"

      http\_archive(
      name = "rules\_jvm\_external",
      strip\_prefix = "rules\_jvm\_external-%s" % RULES\_JVM\_EXTERNAL\_TAG,
      sha256 = RULES\_JVM\_EXTERNAL\_SHA,
      url = "[https://github.com/bazelbuild/rules\_jvm\_external/archive/%s.zip](https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip)" % RULES\_JVM\_EXTERNAL\_TAG,
      )

      load("@rules\_jvm\_external//:repositories.bzl", "rules\_jvm\_external\_deps")
      rules\_jvm\_external\_deps()
      load("@rules\_jvm\_external//:setup.bzl", "rules\_jvm\_external\_setup")
      rules\_jvm\_external\_setup()

      load("@rules\_jvm\_external//:defs.bzl", "maven\_install")
      maven\_install(
      name = "px\_deps",
      artifacts = \[
      "org.antlr:antlr4:4.11.1",
      ],
      repositories = \[
      "[https://repo1.maven.org/maven2](https://repo1.maven.org/maven2)",
      ],
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Maven Extension</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      bazel\_dep(name = "rules\_jvm\_external", version = "6.8")

      maven = use\_extension("@rules\_jvm\_external//:extensions.bzl", "maven")
      use\_repo(maven, "px\_deps")

      maven.artifact(
      name = "px\_deps",
      group = "org.antlr",
      artifact = "antlr4",
      version = "4.11.1"
      )
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Repo rule</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      load("@bazel\_tools//tools/build\_defs/repo:http.bzl", "http\_archive")

      http\_archive(
      name = "com\_github\_cockroachdb\_cockroach",
      sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502",
      strip\_prefix = "cockroach-22.1.6",
      url = "[https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz](https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz)",
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Repo rule</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      http\_archive = use\_repo\_rule("@bazel\_tools//tools/build\_defs/repo:http.bzl", "http\_archive")

      http\_archive(
      name = "com\_github\_cockroachdb\_cockroach",
      url = "[https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz](https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz)",
      sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502",
      strip\_prefix = "cockroach-22.1.6",
      )
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<div style={{display: "flex", flexWrap: "wrap", gap: "16px"}}>
  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>WORKSPACE - Module extension</strong></p>

    <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
      load(":my\_custom\_macro.bzl", "my\_custom\_macro")

      my\_custom\_macro(
      name = "my\_custom\_repo",
      )
    </pre>
  </div>

  <div style={{flex: "1", minWidth: "300px"}}>
    <p><strong>MODULE.bazel - Module extension</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      extension\_for\_my\_custom\_macro = use\_extension("//:extension\_for\_my\_custom\_macro.bzl", "extension\_for\_my\_custom\_macro")
      use\_repo(extension\_for\_my\_custom\_macro, "my\_custom\_repo")
    </pre>

    <p><strong>extension\_for\_my\_custom\_macro.bzl</strong></p>

    <pre class="prettyprint lang-py" style={{fontSize: "12px"}}>
      load("//:my\_custom\_macro.bzl", "my\_custom\_macro")

      def \_extension\_for\_my\_custom\_macro\_impl(ctx):
      my\_custom\_macro(
      name = "my\_custom\_repo",
      )

      extension\_for\_my\_custom\_macro = module\_extension(implementation = \_extension\_for\_my\_custom\_macro\_impl)
    </pre>
  </div>
</div>

<hr style={{height: "1px", backgroundColor: "black", border: "none"}} />

<h2 id="migration-tool-tips">
  Tips with debugging
</h2>

This section provides useful commands and information to help debug issues that
may arise during the Bzlmod migration.

<h3 id="debugging-useful-tips">
  Useful tips
</h3>

* Override version - Not rarely it happens that upgrading the version of a
  dependency causes troubles. Bzlmod could change the version of the
  dependency due to the [MVS algorithm](/external/module#version-selection).
  In order to use the same or similar version as it was in the WORKSPACE,
  override it with
  [single\_version\_override](/rules/lib/globals/module#single_version_override).
  Note that this is useful for debugging differences between WORKSPACE and
  Bzlmod, but you shouldn't rely on this feature in the long term.

  `single_version_override(module_name = "{dep_name}", version = "{version}")`

* Use [bazel mod](/external/mod-command#syntax) command.
  * Check the version of a specified repo with `show_repo`
    command. For example:

    `bazel mod show_repo @rules_python`

  * Check information about a module extension with the `show_extension`
    command. For example:

    `bazel mod show_extension @rules_python//python/extensions:pip.bzl%pip`

* Use [vendor mode](/external/vendor) to create a local copy of a repo when
  you want to monitor or control the source of the repo. For example:

  `bazel vendor --enable_bzlmod --vendor_dir=vendor_src --repo=@protobuf`

<h3 id="migration-tool-report-generation">
  Migration Report Generation
</h3>

This file is updated with each run of the migration script or it's generated
from scratch if it's the first run or if the [`--i` flag](#migration-script-flags) is used. The report contains:

* Command for local testing.

* List of direct dependencies (at least the ones which are directly used in
  the project).

* For each dependency, a drop-down menu for checking where the repository was
  declared in the `WORKSPACE` file, which is particularly useful for the
  debugging. You can see it as:

  <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
    > Click here to see where and how the repo was declared in the WORKSPACE
    > file
  </pre>

* For each dependency, how it was implemented in `MODULE.bazel` file. From the
  earlier [Migration Example](#migration-tool-example), that would look as:

  1. Bazel module Dependency - `Migration of rules_python`

     <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
       Found perfect name match in BCR: rules\_python
       Found partially name matches in BCR: rules\_python\_gazelle\_plugin

       It has been introduced as a Bazel module:
       `bazel_dep(name = "rules_python", version = "1.6.1")`
     </pre>

  * The script will automatically use the `perfect name match` if it finds
    it. In case of an error, you can double check if the name was correctly
    added.

  2. Python extension - `Migration of my_python_deps`

     <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
       pip.parse(
       hub\_name = "my\_python\_deps",
       requirements\_lock = "//:requirements\_lock.txt",
       python\_version = "3.11",
       )
       use\_repo(pip, "my\_python\_deps")
     </pre>

  3. Maven extension - `Migration of org.antlr (px_deps):`

     <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
       maven.artifact(
       name = "px\_deps",
       group = "org.antlr",
       artifact = "antlr4",
       version = "4.11.1"
       )
     </pre>

  4. Go extension - `Migration of org_golang_x_net`

     <pre class="prettyprint lang-java" style={{fontSize: "12px"}}>
       go\_deps.from\_file(go\_mod = "//:go.mod")
       go\_sdk.from\_file(go\_mod = "//:go.mod")

       go\_deps.gazelle\_override(
       path = "golang.org/x/net",
       directives = \[
       "gazelle:proto disable",
       "gazelle:go\_naming\_convention import",
       ],
       )
     </pre>

  * It has been introduced as a go module with the help of `go.mod`. If
    `go.mod` and `go.sum` are not available, go module is added directly
    to the `MODULE.bazel` file.
  * `gazelle_override` is used for adding specific directives.

<h2 id="useful-links">
  Useful links
</h2>

* Official pages for the external extensions
  * [rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external/blob/master/docs/bzlmod.md)
  * [rules\_go](https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md)
  * [rules\_python](https://rules-python.readthedocs.io/en/latest/pypi/download.html)
* Community posts and videos
  * [Migrating to Bazel Modules](https://blog.engflow.com/2025/01/16/migrating-to-bazel-modules-aka-bzlmod---module-extensions/index.html#migrating-to-bazel-modules-aka-bzlmod-module-extensions).
  * [Moving to Bzlmod](https://www.youtube.com/watch?v=W9uXRYLVHUk).
  * [How Uber Manages Go Dependencies with Bzlmod](https://www.youtube.com/watch?v=hIqzkUE_pSY).

<h2 id="feedback">
  Feedback
</h2>

If you would like to contribute, do so by creating an Issue or PR at
[bazel-central-registry](https://github.com/bazelbuild/bazel-central-registry).
