keywords: bzlmod

{# disableFinding(LINE_OVER_80_LINK) #}
{# disableFinding(SNIPPET_NO_LANG) #}
{# disableFinding(LINK_MISSING_ID) #}
{# disableFinding("repo") #}

---
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].

## Core Functionality {:#migration-tool-core-functionality}

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).

## How to Use the Migration Tool {:#migration-tool-how-to-use}

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
    bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
    ```

### Command for running the script {:#migration-script-command}

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

<pre class="prettyprint lang-shell" style="font-size: 12px;">
# Clone the Bazel Central Registry repository
git clone 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 &lt;your project root&gt;
migrate2bzlmod -t &lt;targets&gt;
</pre>

### Files generated by this script {:#migration-script-files}

*   `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).

### Flags {:#migration-script-flags}

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.

### Post-migration cleanup {:#post-migration-cleanup}

*   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 -- #`.

## Migration Example {:#migration-tool-example}

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
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
"""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="font-size: 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="font-weight: 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).

### Transformations {:#migration-tool-transformations}

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

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Bazel Module</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 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",
)
</pre>
  </div>
  <div style="flex: 1; min-width: 300px;">
    <p><strong>MODULE.bazel - Bazel Module</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 12px;">
bazel_dep(name = "rules_shell", version = "0.6.1")
</pre>
  </div>
</div>

<hr style="height: 1px; background-color: black; border: none;">

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Go Extension</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 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://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",
)
</pre>
  </div>
  <div style="flex: 1; min-width: 300px;">
    <p><strong>MODULE.bazel - Go Extension</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 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; background-color: black; border: none;">

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Python Extension</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 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",
)

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; min-width: 300px;">
    <p><strong>MODULE.bazel - Python Extension</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 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; background-color: black; border: none;">

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Maven Extension</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 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" % 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",
    ],
)
</pre>
  </div>
  <div style="flex: 1; min-width: 300px;">
    <p><strong>MODULE.bazel - Maven Extension</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 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; background-color: black; border: none;">

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Repo rule</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 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",
)
</pre>
  </div>
  <div style="flex: 1; min-width: 300px;">
    <p><strong>MODULE.bazel - Repo rule</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 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",
  sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502",
  strip_prefix = "cockroach-22.1.6",
)
</pre>
  </div>
</div>

<hr style="height: 1px; background-color: black; border: none;">

<div style="display: flex; flex-wrap: wrap; gap: 16px;">
  <div style="flex: 1; min-width: 300px;">
    <p><strong>WORKSPACE - Module extension</strong></p>
    <pre class="prettyprint lang-java" style="font-size: 12px;">
load(":my_custom_macro.bzl", "my_custom_macro")

my_custom_macro(
    name = "my_custom_repo",
)
</pre>
  </div>
  <div style="flex: 1; min-width: 300px;">
    <p><strong>MODULE.bazel - Module extension</strong></p>
    <pre class="prettyprint lang-py" style="font-size: 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="font-size: 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; background-color: black; border: none;">

## Tips with debugging {:#migration-tool-tips}

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

### Useful tips {:#debugging-useful-tips}

*   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`

### Migration Report Generation {:#migration-tool-report-generation}

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="font-size: 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="font-size: 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="font-size: 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="font-size: 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="font-size: 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.

## Useful links {:#useful-links}

* 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).

## Feedback {:#feedback}

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).
