Skip to main content

How to configure the Moderne CLI to work with internal tools

This guide walks you through configuring the Moderne CLI to work in environments with restricted internet access or internal artifact repositories. The instructions apply to any Moderne edition (Standard, Enterprise, or DX) — what matters is that the CLI fetches its distribution, dependencies, and recipe JARs from your internal infrastructure rather than reaching out to the public internet. By the end of this guide, you'll have the CLI installed from your internal mirror, configured against your Maven settings and recipe artifact repository, and ready to run OpenRewrite recipes against your repositories.

Assumptions

  • You have an internal mirror of Maven Central (or some other internal artifact repository)
  • You have the ability to download and add artifacts from Maven Central to your internal artifact repository

Installation and configuration

Step 0: Ensure required artifacts exist in your internal artifact repository

Before installing the CLI, please ensure your internal artifact repository contains the following artifacts:

  • The Moderne CLI — distributed as a platform-specific self-extracting installer that bundles the modw wrapper, a Java 25 runtime, and the CLI JAR. It's published to Maven Central under platform-specific artifact IDs: moderne-cli-linux, moderne-cli-osx, and moderne-cli-windows.
  • Recipe modules — see the latest versions of every OpenRewrite module reference for the full list of recipe JARs and a ready-to-run CLI install command. The reference includes both the open-source OpenRewrite recipes (org.openrewrite.*) and Moderne's proprietary recipes (io.moderne.recipe).

If your mirror is configured as a remote proxy of Maven Central (e.g., a virtual repository in Artifactory or a proxy repo in Nexus), most of this happens automatically — artifacts are fetched on demand and cached. If your mirror requires explicit sync-on-approval, each version you wish to use must be synced before users can install or upgrade.

Step 1: Install the CLI from your internal mirror

The CLI ships as a platform-specific installer that bundles the modw wrapper, a Java 25 runtime, and the CLI JAR. On Linux/macOS it's a self-extracting shell script (.sh); on Windows it's a zip archive (.zip) containing an install.cmd to run after extracting. Either way, installation drops everything into ~/.moderne/cli/ (or %USERPROFILE%\.moderne\cli on Windows) without further network access.

Download the platform-appropriate distribution from your internal mirror. For example, for Linux x86_64:

curl -fL -o moderne-cli.sh \
"https://internal-mirror.example.com/io/moderne/moderne-cli-linux/4.2.1/moderne-cli-linux-4.2.9.sh"

Replace 4.2.1 with the version you intend to install, and adjust the artifact name to match your platform (moderne-cli-linux, or moderne-cli-osx).

Then run the installer:

bash moderne-cli.sh

The installer adds ~/.moderne/cli/bin to your PATH and configures shell completion. Open a new terminal (or source your shell's rc file) to pick up the changes.

The macOS distribution bundles a JRE for Apple Silicon only. Intel Mac users will need to install a Java 25+ runtime separately and ensure it's discoverable by the wrapper — see how the wrapper finds Java for details.

Step 2: Pin the CLI version

The wrapper reads its global configuration from ~/.moderne/cli/dist/moderne-wrapper.properties. By default (when no version is configured), the wrapper resolves RELEASE against https://repo1.maven.org/maven2 - which won't work in an environment that cannot reach Maven Central directly.

Before running any mod command, please pin the wrapper to the version you installed in Step 1:

echo "version=4.2.1" > ~/.moderne/cli/dist/moderne-wrapper.properties

Replace 4.2.1 with the version you installed.

Pinning a version is required in environments that cannot reach repo1.maven.org. The wrapper's RELEASE and LATEST resolution always queries Maven Central for maven-metadata.xml, regardless of any distributionUrl setting. If Maven Central is not reachable and no version is pinned, every modw invocation will fail at version resolution.

There are two ways to upgrade the CLI later:

  • Re-run the installer (Step 1) for the new version, then update version= in this file.
  • Bump version= and let the wrapper download the new distribution. This requires also setting distributionUrl in this file to point at your internal mirror — see the air-gapped or restricted environments section of the CLI wrapper guide for the URL template. Once configured, you can also bump versions via mod wrapper --global --version=<new-version>.

You should now be able to verify the installation by running mod --version.

For more on how the wrapper works (auto-update behavior, distribution URLs, JDK selection, environment variables), see the CLI wrapper and version management guide.

Step 3: Configure the CLI to use your license

In order to run recipes, you'll need to ensure the CLI is configured with a license. You should have received a license from us. With that license, please run the following command:

mod config license edit <license-you-were-provided>

For more information on the Moderne CLI license, please see our license documentation.

(Optional) Step 4: Configure the CLI to point to your internal artifact repository

If your Maven settings file is not in the default location, please run the following command to point the CLI to your Maven settings file. If it is in the default location, skip to step 5.

mod config build maven settings edit /path/to/maven/settings/file

In order for the CLI to download dependencies/lookup versions as needed, it will need to be provided with the path to your Maven settings file. This likely exists on developer machines for the sake of redirecting requests from Maven Central to an internal artifact instance.

(Optional) Step 5: Configure the CLI to point to an internal Artifactory to download recipes

If you have an internal Artifactory instance where you plan on storing recipes, please direct the CLI to it by running the following command:

mod config recipes artifacts artifactory edit

Step 6: Install recipe JARs

The next thing you need to do is ensure your internal artifact repository has all of the recipe JARS (assuming that your artifact repository is not a pure remote proxy to Maven Central already or that there isn't some automatic procurement step at dependency resolution time).

With that done, you'll need to run the mod config recipes jar install command and provide it with the JARs you wish to install.

The latest version of every JAR and the CLI command to install those latest versions can be found at the bottom of the latest versions of every OpenRewrite module doc. This is automatically updated whenever we do a new release.

Step 7: Create a list of your repositories

In order for the CLI to run recipes against your code, you will need to provide it with a repos.csv file. The first row in the CSV file should be a header row that lists out the columns you intend to provide. After that, each row will represent a repository. At a minimum, you should include a URL to clone said repository – but you can also provide other columns as needed.

Here is an example of a simple CSV file for cloning some OpenRewrite repositories:

cloneUrl
https://github.com/openrewrite/rewrite-spring
https://github.com/openrewrite/rewrite-recipe-markdown-generator
https://github.com/openrewrite/rewrite-docs
https://github.com/openrewrite/rewrite

For a complete list of all supported columns and their descriptions, please see the repos.csv reference documentation.

To assist with creating a repos.csv file, we've written some bash scripts that will generate a simple CSV file for you:

Step 1: Install and configure the GitHub CLI if you haven't already done so.

Step 2: Create a github.sh file like:

github.sh
#!/bin/bash

if [ -z "$1" ]; then
echo "Usage: $0 <org>"
echo "Example: $0 openrewrite"
exit 1
fi

organization=$1

gh repo list "$organization" \
--json url,defaultBranchRef \
--jq '["cloneUrl","branch"], (.[] | [.url, .defaultBranchRef.name]) | @csv'

Step 3: Grant the script access to be run:

chmod +x github.sh

Step 4: Run the script and pipe it to a repos.csv file:

./github.sh YOUR_ORG_NAME > repos.csv

If everything was done correctly, you should have a repos.csv file that looks similar to the following:

"cloneUrl","branch"
"https://github.com/openrewrite/rewrite","main"
"https://github.com/openrewrite/rewrite-python","main"
"https://github.com/openrewrite/rewrite-openapi","main"
"https://github.com/openrewrite/rewrite-static-analysis","main"
"https://github.com/openrewrite/rewrite-java-dependencies","main"
"https://github.com/openrewrite/rewrite-docs","master"

Step 8: Clone your repositories

Create a directory somewhere on your machine where you'd like the CLI to clone the repositories to. Then navigate to that directory, copy the repos.csv file to it, and run the following command:

mod git sync csv . repos.csv --with-sources

Step 9: Build your repositories

With all of the repositories cloned to your machine, you can then build LSTs for them by running the following command:

mod build .

With the LSTs built, you're ready to run recipes against them! Consider checking out the using the CLI section in the getting started guide to see some ways you can use the CLI.

Standardizing CLI installation across your team

For team-wide standardization, consider committing a Moderne CLI wrapper to a shared repository. This works similarly to the Gradle wrapper: every developer and CI job uses a consistent, version-pinned CLI, and the wrapper downloads the CLI installer from your internal mirror on first run.

To set this up:

  1. On a machine that can run mod, generate the wrapper files with mod wrapper --version <pinned-version>. This produces modw, modw.cmd, and moderne/wrapper/moderne-wrapper.properties in the current directory.

  2. Edit the generated moderne-wrapper.properties file to set distributionUrl to your internal mirror, along with any required credentials. For example:

    version=4.2.1
    distributionUrl=https://internal-mirror.example.com/io/moderne/moderne-cli-${platform}/${version}/moderne-cli-${platform}-${version}.sh
    jdkUrl=skip
  3. Commit modw, modw.cmd, and moderne/wrapper/moderne-wrapper.properties to your shared repository. Anyone who clones it can then run ./modw <command> — the wrapper will fetch the pinned distribution from your internal mirror on first invocation.

For full details on the wrapper's properties, environment variables, JDK discovery, and authentication options, see the CLI wrapper and version management guide.