Getting started with the Moderne CLI
The Moderne CLI is a command line tool that complements the Moderne Platform and Moderne DX, enabling you to build Lossless Semantic Tree (LST) artifacts across many repositories and run recipes against all of them from your local machine. It also provides substantial benefits for creating and testing your own recipes.
To ensure you can use the Moderne CLI successfully, in this guide, we will walk you through everything you need to get started – from installation, to configuration, to examples demonstrating how to use it.
The examples in this guide use Moderne CLI version 3.45.5
.
Installation and configuration
Choose the installation path that matches your setup:
- Standard Edition
- Enterprise Edition
- Moderne DX
These instructions apply to Standard Edition customers and users of the public app.moderne.io instance.
Step 1: Download the CLI
- Go to app.moderne.io and sign in.
- Click on
Help
in the bottom left-hand corner and select the version of the CLI you want to download (Stable or Staging). In general, you should use staging when working with the CLI locally, and you should use stable for crucial mass-ingest process runs. - Either press the download button for your appropriate OS, or select the installation method in the provided table. We recommend using HomeBrew or Chocolatey if you have access to either.

- If you chose to install the CLI without a package manager, you'll need to save it somewhere that your terminal can access. This could involve updating your
PATH
to point to a specific location – or this could involve putting it in a directory that's already on yourPATH
(such as a/user/bin
directory).- Remember to refresh any open terminals if you modify the
PATH
.
- Remember to refresh any open terminals if you modify the
If everything was configured correctly, you should be able to type mod
into your terminal and see a list of commands:mod command results
➜ mod
Moderne CLI 3.45.5
Usage:
mod [-h] [--version] [COMMAND]
Description:
Automated code remediation.
Options:
-h, --help Display this help message.
--version Display version info.
Commands:
afterburner (INCUBATING) Indexes built LSTs to accelerate recipe
execution.
audit (INCUBATING) Perform an audit of recent activity.
batch Add batch changes to the Moderne platform.
build Generates LST artifacts for one or more repositories.
clean Clean build and run artifacts produced by the CLI.
config Global configuration options that are required by some
CLI commands.
devcenter Generate DevCenter dashboards.
exec Execute an arbitrary shell command recursively on
selected repository roots.
generate-completion Generate bash/zsh completion script for mod.
git Multi-repository git operations.
log Manages a log aggregate.
list Lists the repositories that can be built and published.
monitor (INCUBATING) Launches an HTTP server used to monitor the
CLI.
publish Publishes the LST artifacts for one or more projects.
run Runs an OpenRewrite recipe locally on pre-built LSTs.
run-history Get information about the most recent recipe runs. This
will be transitioning to mod audit runs list
eventually. A deprecation notice will be added here
when we suggest adopting the alternative.
study Produces studies from OpenRewrite recipe data tables
locally.
Step 2: (Optional) Set up auto-completion in your terminal (Unix terminals only)
The Moderne CLI offers a command which generates a completion script that can be used to set up auto-completion in your terminal. After initializing this script, you can type mod config
and press tab and then your terminal will offer suggestions for the sub-commands or parameters:

To configure this for the terminal you're using, please enter the following command in your terminal:
source <(mod generate-completion)
Or, if you want to configure auto-completion so that it works for every terminal instance you make, please update your ~/.zshrc
or ~/.bashrc
file and add this command to the bottom of it:
# The next line enables shell command completion for mod
source <(mod generate-completion)
Step 3: Connect the CLI to Moderne
Connecting the CLI to Moderne is necessary to:
- Quickly sync the recipe catalog from Moderne to your local machine
- Download pre-built LSTs from Moderne so you can quickly run recipes locally
- Receive organizational information, so you can clone/build/run groups of repositories more easily
To set up this connection, you'll first need to create an access token for the CLI to use:
- Navigate to https://app.moderne.io/settings/access-token
- Enter a human-readable name for the token (e.g., cli-token)
- Press
Generate
- Copy the
install on your workstation
command and paste it into your command line. This command should look something like:
mod config moderne edit https://app.moderne.io --token mat-YOUR_TOKEN_HERE
- If everything worked, you should see a
MOD SUCCEEDED
message

Step 4: Install recipes
With the Moderne connection established, you can download recipes to your local machine by running the following command:
mod config recipes moderne sync
Occasionally, a few of the recipes may fail to sync properly and return the message ! Failed to install
. If the majority of the recipes installed successfully, however, you will see the MOD PARTIALLY SUCCEEDED
message when the command completes, and you can still continue on without a problem for the purposes of this tutorial.
This will grab all of the recipes from the tenant you specified in mod config
– so please expect this command to take a few minutes to download the recipes.
If your organization is paying for the Enterprise Edition of Moderne and you have a private Moderne instance (e.g.,
https://yourcompany.moderne.io
), please follow these instructions.
Step 1: Download the CLI
- Go to your private tenant URL (e.g.,
https://yourcompany.moderne.io
) and sign in. - Click on
Help
in the bottom left-hand corner and select the version of the CLI you want to download (Stable or Staging). In general, you should use staging when working with the CLI locally, and you should use stable for crucial mass-ingest process runs. - Either press the download button for your appropriate OS, or select the installation method in the provided table. We recommend using HomeBrew or Chocolatey if you have access to either.

- If you chose to install the CLI without a package manager, you'll need to save it somewhere that your terminal can access. This could involve updating your
PATH
to point to a specific location – or this could involve putting it in a directory that's already on yourPATH
(such as a/user/bin
directory).- Remember to refresh any open terminals if you modify the
PATH
.
- Remember to refresh any open terminals if you modify the
If everything was configured correctly, you should be able to type mod
into your terminal and see a list of commands:mod command results
➜ mod
Moderne CLI 3.45.5
Usage:
mod [-h] [--version] [COMMAND]
Description:
Automated code remediation.
Options:
-h, --help Display this help message.
--version Display version info.
Commands:
afterburner (INCUBATING) Indexes built LSTs to accelerate recipe
execution.
audit (INCUBATING) Perform an audit of recent activity.
batch Add batch changes to the Moderne platform.
build Generates LST artifacts for one or more repositories.
clean Clean build and run artifacts produced by the CLI.
config Global configuration options that are required by some
CLI commands.
devcenter Generate DevCenter dashboards.
exec Execute an arbitrary shell command recursively on
selected repository roots.
generate-completion Generate bash/zsh completion script for mod.
git Multi-repository git operations.
log Manages a log aggregate.
list Lists the repositories that can be built and published.
monitor (INCUBATING) Launches an HTTP server used to monitor the
CLI.
publish Publishes the LST artifacts for one or more projects.
run Runs an OpenRewrite recipe locally on pre-built LSTs.
run-history Get information about the most recent recipe runs. This
will be transitioning to mod audit runs list
eventually. A deprecation notice will be added here
when we suggest adopting the alternative.
study Produces studies from OpenRewrite recipe data tables
locally.
Step 2: (Optional) Set up auto-completion in your terminal (Unix terminals only)
The Moderne CLI offers a command which generates a completion script that can be used to set up auto-completion in your terminal. After initializing this script, you can type mod config
and press tab and then your terminal will offer suggestions for the sub-commands or parameters:

To configure this for the terminal you're using, please enter the following command in your terminal:
source <(mod generate-completion)
Or, if you want to configure auto-completion so that it works for every terminal instance you make, please update your ~/.zshrc
or ~/.bashrc
file and add this command to the bottom of it:
# The next line enables shell command completion for mod
source <(mod generate-completion)
Step 3: Connect the CLI to your tenant
Connecting the CLI to your Moderne tenant is necessary to:
- Quickly sync the recipe catalog from your tenant to your local machine
- Download pre-built LSTs from your tenant so you can quickly run recipes locally
- Receive organizational information specific to your company, so you can clone/build/run groups of repositories more easily
To set up this connection, you'll first need to create an access token for the CLI to use:
- Navigate to
https://yourcompany.moderne.io/settings/access-token
(replaceyourcompany
with your tenant name) - Enter a human-readable name for the token (e.g., cli-token)
- Press
Generate
- Copy the
install on your workstation
command and paste it into your command line. This command should look something like:
mod config moderne edit https://yourcompany.moderne.io --token mat-YOUR_TOKEN_HERE
- If everything worked, you should see a
MOD SUCCEEDED
message

Step 4: Install recipes
With the Moderne connection established, you can download recipes to your local machine by running the following command:
mod config recipes moderne sync
Occasionally, a few of the recipes may fail to sync properly and return the message ! Failed to install
. If the majority of the recipes installed successfully, however, you will see the MOD PARTIALLY SUCCEEDED
message when the command completes, and you can still continue on without a problem for the purposes of this tutorial.
This will grab all of the recipes from your tenant – so please expect this command to take a few minutes to download the recipes.
If your organization is paying for Moderne DX and you need to set up the CLI in an air-gapped or a restricted environment, please follow the instructions in our installing and configuring the CLI for DX users guide.
Using the CLI
With installation and configuration complete, you're ready to use the CLI. This section will guide you through common workflows and commands.
For a hands-on tutorial using public repositories, check out our Moderne CLI workshop.
The Moderne CLI was not designed to run multiple commands simultaneously. Please only execute one command at a time.
Setting up your workspace
The most common (and recommended) way of using the Moderne CLI is to run recipes against pre-built LSTs that you download to your machine. For this path, you'll want to create a directory that you can clone the LSTs and code to:
mkdir /path/to/your/moderne/workspace
cd /path/to/your/moderne/workspace
It's also possible to run recipes on code you have already checked out on your machine – in which case you'll want to cd
into that directory and then build the LSTs:
cd /path/to/your/repos
mod build .
Syncing Moderne organizations
If you already have repositories you want to work with checked out locally, skip to the building LSTs section.
Rather than needing to manually clone every repository you want to run a recipe against, Moderne offers the ability to download LSTs and code for pre-defined groups of repositories.
- Standard Edition
- Enterprise Edition
- Moderne DX
Viewing available organizations
To see what organizations you have access to in app.moderne.io
, run the following command:
mod config moderne organizations show
You should see something like this:
Moderne CLI 3.45.5
⏺ Retrieving the configured organizations
ALL (12345)
Default (11)
JetBrains (170)
Moderne (116)
Moderne - Public (8)
Moderne AI (8)
Moderne SaaS (26)
Moderne Libraries (10)
Moderne Microservices (15)
Moderne UI (1)
Recipes (28)
Smoke test (6)
Open Source (48316)
AirBnB (19)
Alibaba (363)
Amazon (95)
Android (129)
Antlr (10)
Atlassian (1)
BNY (3)
C# (459)
Cloud Foundry (7)
DataStax (124)
Eclipse Foundation (295)
Eclipse Platform (7)
Elastic Search (35)
Facebook (19)
FasterXML (48)
FINOS (29)
Forks (34)
Google (764)
Gradle (61)
Gradle Plugins (46)
Green Button Alliance (3)
...
Downloading LSTs and code
Once you've decided what organization you want to clone, you can download the LSTs and code to your machine by running the following command:
mod git sync moderne /path/to/your/workspace "<organization-name>" --with-sources
Make sure to replace the path and organization with the one you want. If you don't want to download the code and just want to download the LSTs, you can remove the --with-sources
flag.
If you need to enter an SSH passphrase to clone repositories, please see our SSH keys with passphrases guide before continuing.
Viewing available organizations
To see what organizations you have access to in your Moderne tenant, run the following command:
mod config moderne organizations show
You should see something that looks similar to this (it will have your organizations instead):
Moderne CLI 3.45.5
⏺ Retrieving the configured organizations
ALL (12345)
Default (11)
JetBrains (170)
Moderne (116)
Moderne - Public (8)
Moderne AI (8)
Moderne SaaS (26)
Moderne Libraries (10)
Moderne Microservices (15)
Moderne UI (1)
Recipes (28)
Smoke test (6)
Open Source (48316)
AirBnB (19)
Alibaba (363)
Amazon (95)
Android (129)
Antlr (10)
Atlassian (1)
BNY (3)
C# (459)
Cloud Foundry (7)
DataStax (124)
Eclipse Foundation (295)
Eclipse Platform (7)
Elastic Search (35)
Facebook (19)
FasterXML (48)
FINOS (29)
Forks (34)
Google (764)
Gradle (61)
Gradle Plugins (46)
Green Button Alliance (3)
...
Downloading LSTs and code
Once you've decided what organization you want to clone, you can download the LSTs and code to your machine by running the following command:
mod git sync moderne /path/to/your/workspace "<organization-name>" --with-sources
Make sure to replace the path and organization with the one you want. If you don't want to download the code and just want to download the LSTs, you can remove the --with-sources
flag.
If you need to enter an SSH passphrase to clone repositories, please see our SSH keys with passphrases guide before continuing.
Working with organizations in DX
For Moderne DX customers, organizations are defined in your organization's repos.csv file (or in a repos-lock.csv
file shared with you). It's up to your team to figure out the best way to distribute this file. That being said, we'd recommend having your mass ingest pipeline publish this CSV to S3 (or something similar) so people can easily download this file to their machines.
Once you have the CSV downloaded, you can either clone all of the repositories in that file and then cd
into the organization (a specific directory) you care about – or you can filter the CSV file down to just the ones you care about and then clone those.
In either case, the command you should run is:
mod git sync csv /path/to/your/workspace repos.csv --with-sources
If you don't want to download the code and just want to download the LSTs, you can remove the --with-sources
flag.
Building LSTs
If you need to build the LSTs locally rather than downloading them, you can run the following command:
mod build /path/to/your/workspace
If a project fails to build, it might require additional configuration. See mod config build for customization options. If an LST doesn't build, running a recipe will just skip that project rather than error on it.
Running recipes
Once you have the LSTs downloaded or built, you can then run recipes against them.
Basic recipe execution
To run a recipe against all repositories in a specific directory:
mod run /path/to/your/workspace --recipe <RecipeName>
## For example:
mod run /path/to/your/workspace --recipe DependencyVulnerabilityCheck
If multiple recipes have similar names, you'll be prompted to select the specific one you want. You can avoid this by using the fully qualified recipe name such as in the following example:
mod run . --recipe org.openrewrite.java.dependencies.DependencyVulnerabilityCheck
Running recipes with parameters
Some recipes accept parameters to customize their behavior:
mod run /path/to/your/workspace --recipe <RecipeName> -P<parameterName>=<value>
## For example:
mod run . --recipe FindMethods -PmethodPattern="java.util.List add(..)"
Examining results
To learn more about what changed, you can command/ctrl click on the Fix results
link in the output.
Working with data tables
Many recipes produce data tables on top of changing the code. Think of data tables as spreadsheets that recipes create to show you patterns and insights they discovered while analyzing your code.
Viewing available data tables
After running a recipe, the CLI will suggest data tables you can examine such as in the following example:
⏺ What to do next
> Run mod study to examine the following data tables produced by this recipe:
> mod study . --last-recipe-run --data-table VulnerabilityReport
> mod study . --last-recipe-run --data-table MavenMetadataFailures
> mod study . --last-recipe-run --data-table RecipeRunStats
> mod study . --last-recipe-run --data-table SourcesFileResults
Generating data tables
To generate a data table from the last recipe run, you can copy one of the commands listed after a recipe run. It should look something like this:
mod study /path/to/your/workspace --last-recipe-run --data-table <TableName>
This command will generate a CSV file that you can then analyze.
Customizing output format
You can use the Moderne CLI to output other types of data based on your needs. For instance, you may want it to create a markdown file or a JSON file instead. Below are some examples of how you can change the output format:
Export specific columns as JSON:
mod study . --last-recipe-run --data-table <TableName> --json <column1>,<column2>
Use templates for custom formatting:
mod study . --last-recipe-run --data-table MethodCalls --json sourceFile,method --template '{{"# Search results\n\n"}}{{range .}}{{"* "}}{{.sourceFile}}{{"\n```\n"}}{{.method}}{{"\n```\n"}}{{end}}' > methods.md
This flexibility allows you to create custom reports tailored to your organization's needs.
Committing changes and creating PRs
After running recipes, you'll typically want to review, test, and commit the changes. The CLI provides commands to help manage these changes across multiple repositories.
Creating branches
After running a recipe, the changes exist only as patches (so if you cd
into any of the repos, you would see no changes). While you could apply the patches to the branches you have checked out, it's generally preferable to make changes inside of a new branch and then submit a PR for said branch:
mod git checkout /path/to/your/workspace -b <branch-name> --last-recipe-run
This creates a new branch in each repository that has changes from the recipe run.
Applying changes
To apply the recipe changes to your repositories, run the following command:
mod git apply /path/to/your/workspace --last-recipe-run
After applying changes, you can navigate to individual repositories and run git status
to see the uncommitted changes. This is a good time to run tests and verify the changes work as expected.
Staging and committing changes
Once you've tested the changes and decided you want to commit them, you'll need to run the following command to stage the changes for commit:
mod git add /path/to/your/workspace --last-recipe-run
Then you can commit the changes:
mod git commit /path/to/your/workspace -m "<your commit message>" --last-recipe-run
GPG signing is not currently supported by the mod git commit
command. If you use GPG signing, you'll need to disable it temporarily or manually commit the changes in each repository.
Creating pull requests
After committing changes, you can push them and create pull requests:
Push changes to remote:
mod git push /path/to/your/workspace --last-recipe-run
If needed, you can also specify an upstream branch:
mod git push /path/to/your/workspace --last-recipe-run --set-upstream <branch-name>
You can also create PRs using the GitHub CLI:
mod exec . --last-recipe-run -- gh pr create --title "<PR title>"
For more options, see the CLI reference documentation.
Additional information
If you want to learn more about the Moderne CLI, we'd encourage you to check out the following docs:
- Layered configuration in the CLI
- JDK selection and configuration
- Using the Moderne IntelliJ plugin with the CLI
Or watch the following videos:
Differences between the Moderne CLI and the OpenRewrite build plugins
The OpenRewrite build plugins are designed to run a single recipe on a single repository at a time. When you run a recipe using these plugins, a new LST is produced regardless of whether or not the code for that repository has changed. This LST is temporarily stored in memory and used by the recipe before being discarded at the end of the recipe run. For large projects, this can be problematic as the entire LST must fit in memory for the recipe to work.
In contrast, the Moderne CLI is designed for scale. You can run recipes against multiple repositories at once and the LST does not need to fit into memory. This is because the Moderne CLI uses proprietary code to build the LST up in parts and then serializes/writes it to the disk (as part of the mod build
command). Likewise, the mod run
command will read this LST from the disk in pieces as it runs recipes rather than building the LST every time.
When running the Moderne CLI commands for the first time, you might notice that running a single recipe on a single repository is slower than the OpenRewrite build plugins. This is due to the fact that the OpenRewrite build plugins do not serialize the LST and write it to disk.
However, if you wanted to run more recipes against the same LST, you would see that the Moderne CLI drastically increases in speed compared to the OpenRewrite build plugins as the Moderne CLI can read the pre-built LST and execute recipes against it rather than having to build it again each time. Furthermore, if you wanted to, you could use the Moderne CLI to run a recipe against many repositories at once – which the OpenRewrite build plugins can't do.