Skip to main content

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

The quickest way to see the CLI in action is the quickstart, where a coding agent drives mod for you. This guide is for when you want to run each step yourself, or need to understand what the agent is doing on your behalf. We will walk you through everything from installation, to configuration, to the commands that sync code, run recipes, and turn the results into pull requests.

The examples in this guide use the latest version of the Moderne CLI.

Installation and configuration​

Choose the installation path that matches your setup:

These instructions apply to Standard Edition customers and users of the public app.moderne.io instance.

Install the CLI and log in​

Run the install script for your operating system:

curl https://app.moderne.io/cli | bash

The script installs a lightweight wrapper called modw, with mod as a symlink to it. It makes mod available in your terminal, points the CLI to app.moderne.io, and then opens your browser so you can authorize it. Sign in if you aren't already, then click Yes when asked whether the CLI can create a personal access token on your behalf.

Once you've confirmed, the CLI stores the token on your machine and then syncs the recipe marketplace so you can search and run recipes locally. The sync takes a few minutes.

By default, the token is valid for 365 days. When it expires, run mod login again to renew it. If you need a different expiration period, you can use the --expiration option (e.g., mod login --expiration P180D for 180 days).

On its first run, the wrapper downloads the CLI distribution for your platform and keeps it up to date. Verify the installation by running mod in your terminal:

mod command results
➜ mod

Moderne CLI 4.11.0

Usage:

mod [-h] [--version] [COMMAND]

Description:

Automated code remediation.

Options:

-h, --help Display this help message.
--version Display version info.
Commands:

audit (INCUBATING) Perform an audit of recent activity.
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.
doctor Checks that this machine and the CLI's configuration can build
and publish LSTs.
devcenter Generate DevCenter dashboards.
exec Execute an arbitrary shell command on selected repositories and
partitions.
git Multi-repository git operations.
log Manages a log aggregate.
list Lists the repositories that can be built and published.
login Logs the CLI into Moderne
monitor (INCUBATING) Launches an HTTP server used to monitor the CLI.
prebuild Extracts build metadata without parsing source files.
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.
search Search repositories using trigram indexes.
study Produces studies from OpenRewrite recipe data tables locally.
telemetry Manage CLI telemetry pushed to the configured Moderne tenant.
trace Manages trace analysis tools.
wrapper Create or configure a Moderne wrapper.

Agent Commands:

amp (INCUBATING) Launches an Amp session configured to use mod for
deterministic multi-repository work.
claude (INCUBATING) Launches a Claude Code session configured to use
mod for deterministic multi-repository work.
codex (INCUBATING) Launches a Codex session configured to use mod for
deterministic multi-repository work.
copilot (INCUBATING) Launches a GitHub Copilot session configured to use
mod for deterministic multi-repository work.
cursor (INCUBATING) Launches a Cursor session configured to use mod for
deterministic multi-repository work.
kiro (INCUBATING) Launches a Kiro session configured to use mod for
deterministic multi-repository work.
opencode (INCUBATING) Launches an opencode session configured to use mod
for deterministic multi-repository work.
vscode (INCUBATING) Launches a Visual Studio Code Chat session
configured to use mod for deterministic multi-repository work.
windsurf (INCUBATING) Launches a Windsurf session configured to use mod
for deterministic multi-repository work.

The script also sets up tab completion for bash, zsh, and PowerShell. This means that if you open a new terminal and type mod and then press tab, you can see the list of available commands.

You can also install the CLI with Homebrew or Chocolatey. You will need to configure a few things yourself if you do.

Homebrew and Chocolatey instructions
  • Homebrew (macOS/Linux): brew install moderneinc/moderne/mod
  • Chocolatey (Windows): choco install mod --prerelease

A package manager installs only the wrapper. You will need to connect the CLI to app.moderne.io and authorize it yourself:

mod config moderne edit https://app.moderne.io
mod login

The login command opens your browser for the same authorization, then syncs the recipe marketplace.

Shell completion is not set up for you either. To enable it for the current terminal, run:

source <(mod generate-completion)

To enable it for every terminal you open, add that command to the bottom of your ~/.zshrc or ~/.bashrc file.

Refreshing the recipe marketplace​

Authorizing the CLI syncs the recipe marketplace once. When Moderne publishes new recipes, you can sync it again:

mod config recipes moderne sync -y

Without -y, the command asks for confirmation before replacing the recipes you already have.

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. Feel free to ignore that and continue with the tutorial.

Connecting to internal tools​

If your organization installs the CLI from an internal artifact repository (common for Enterprise and DX deployments), follow our guide to deploying the CLI from an internal artifact repository.

If you also need to point the CLI at other internal tooling (a non-default Maven settings file, an internal Artifactory for recipes, etc.), see our guide to configuring the CLI to work with internal tools.

New recipe releases are published to the Code Genome Project rather than Maven Central. If you don't resolve recipes through an internal mirror, point the CLI at the Code Genome Project so you don't install stale releases.

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.

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 4.11.0

⏺ Retrieving the configured organizations

ALL (56608)
Backend Services (7081)
API (217)
GraphQL (76)
RPC (36)
Frameworks (6779)
JVM Frameworks (4377)
Spring (1949)
Spring Boot (550)
...
Data & ML (2467)
...
Open Source (2235)
Apache (1164)
CNCF (137)
Eclipse Foundation (142)
...
Sample Estate (27)
Java Estate (8)
Java Services (4)
Legacy Java Apps (5)
JavaScript Estate (8)
JavaScript Services (5)
Legacy JavaScript Apps (4)
Python Estate (11)
Legacy Python Apps (6)
Python Services (6)
Platform Engineering (6559)
...

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

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.

Make sure the build tools your projects use are on your PATH. Run mod doctor to see which toolchains the CLI finds on this machine.

Analyzing build results locally​

When building LSTs for many repositories, some may fail due to unique build requirements. The Moderne CLI includes a built-in analytics dashboard for visualizing build failures. Launch it with:

mod trace builds analyze . --last-build

Build Trace Analysis dashboard with build tool charts, success rates, and build time metrics
Build telemetry dashboard view

The dashboard displays build metadata and lets you drill into individual repositories to view logs and troubleshooting suggestions.

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

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 set the upstream tracking reference:

mod git push /path/to/your/workspace --last-recipe-run -u

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.

Uninstalling the CLI​

How you remove the CLI depends on how you installed it.

  1. Delete the CLI directory:

    rm -rf ~/.moderne/cli
  2. Delete any mod and modw links the installer created in ~/.local/bin, ~/bin, or /usr/local/bin:

    rm -f ~/.local/bin/mod ~/.local/bin/modw
  3. If the installer added ~/.moderne/cli/bin to your PATH, remove that line and the completion.bash line from your shell configuration file (such as ~/.zshrc or ~/.bashrc).

Removing the CLI leaves your access tokens and other data in the ~/.moderne directory (%USERPROFILE%\.moderne on Windows). Delete that directory too if you want a clean slate.

Additional information​

If you want to learn more about the Moderne CLI, we'd encourage you to check out the following docs:

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.