Java developers have long been exceptionally well served by IDEs. Formatting source, navigating declarations and usages, reading API documentation, and exploring dependency sources and references are all part of the experience. In the terminal, those same tasks often mean searching dependency caches, locating source archives, and assembling tool arguments by hand. Coding agents encounter these gaps constantly.
ja is a terminal development environment for Java, bringing those capabilities to the command line through small, composable tools. The goal is to make common Java development tasks as accessible to terminal users and coding agents as they are to someone working in an IDE.
It works with module, Maven, and Gradle projects. Your working directory selects the project, and each tool gets the sources, dependencies, and Java options it needs automatically. That includes standard JDK tools such as javac, jdeps, jlink, and jshell.
For module projects, the environment also supports building, testing, and distributing applications directly from module-info.java. A simple program can grow into one module with dependencies, then multiple modules, without introducing a separate build configuration.
Important
This project and its bundled tools are currently in preview. We are collecting feedback for all of the tools together in Discussions.
Note
Netflix engineers should use the internally bundled toolchain rather than installing ja or its tools separately.
Make a JDK 25 or later available through JAVA_HOME, PATH, or an environment manager such as jenv. The installer supports two first-class installation styles.
The default installation links ja and its tools into a development JDK. Selecting that JDK selects the complete toolchain together, which works naturally with environment managers, IDE JDK discovery, JAVA_HOME, and PATH.
On macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/Netflix/ja/main/install.sh | bashOn Windows PowerShell:
irm https://raw.githubusercontent.com/Netflix/ja/main/install.ps1 | iexOn macOS the JDK is installed under ~/Library/Java/JavaVirtualMachines. On Linux and Windows it is installed under ~/.jdks. The source JDK is not modified.
Use the standalone installation when you want to add only the ja command and continue using an existing JDK unchanged:
curl -fsSL https://raw.githubusercontent.com/Netflix/ja/main/install.sh |
bash -s -- --standalone& ([scriptblock]::Create((irm https://raw.githubusercontent.com/Netflix/ja/main/install.ps1))) `
-Installation StandaloneThe installer selects the correct platform archive, installs it alongside applications managed by ja install, and activates ja through the same user command directory. The launcher uses JAVA_HOME when set, then falls back to java on PATH. The archive contains the development tools, but not a JDK. Use a plain JDK: the launcher rejects system modules whose names overlap the bundled application modules, rather than silently using the JDK's copies.
Neither installation modifies shell configuration. The installer prints the activation and completion commands to add to your shell profile. See the installation guide for default locations, custom locations, version pinning, shell setup, and environment-manager guidance.
Take ja for a spin by installing an application:
$ ja install com.github.ricksbrown.cowsay@1.1.0
$ cowsay 'Holy cow, Java modules!'
_________________________
< Holy cow, Java modules! >
-------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||Initialize the current directory as a module, declare its main class, and add a dependency by Java module name:
ja init --main-class com.example.hello.Main com.example.hello
ja require org.apache.commons.text@1.13.1These commands create module-info.java in the current directory without moving existing source. ja records the dependency version alongside the standard requires directive:
/**
* @mainClass com.example.hello.Main
*/
module com.example.hello {
requires org.apache.commons.text; // @1.13.1
}Create com/example/hello/Main.java and use the dependency normally:
package com.example.hello;
import java.util.Map;
import org.apache.commons.text.StringSubstitutor;
public final class Main {
public static void main(String[] arguments) {
var values = Map.of("name", "modules");
System.out.println(StringSubstitutor.replace("Hello, ${name}!", values));
}
}Run your shiny new modular application:
ja runHello, modules!
The working directory determines which modules are in scope. ja supplies each command or tool with the standard Java arguments it accepts for those modules:
ja tool jdepsWhen moving to source control move to a module source path layout, src/com.example.hello. With that layout, ja init creates new modules alongside it under src.
While com.example.hello is fine for this example, for a module you intend to publish, choose a globally meaningful reverse-domain name following Sonatype's namespace conventions, using a domain you own or a namespace you can verify, such as io.github.owner.application.
Several bundled tools underpin the command implementation:
- jig performs module version resolution, compilation and assembly, outputting standard module system arguments for use with other tools. It is also the bridge to and from Maven repositories providing a standalone module proxy and publishing commands
- jfmt formats source using the Code Conventions for the Java Programming Language, adapted for the modern Java language. Avoids the very common whitespace, indentation, import ordering and qualified class references introduced in agent written code
- jist provides source aware symbol search, providing a grep style interface for understanding class files and their associated sources. Gives coding agents access to symbols and sources without indexing, LSPs or MCPs while interoperating with other build tools via an argument file contract
- jdocserver serves locally browsable API documentation
The wiki covers:
- Installation
- Module layout
- Dependencies
- Development
- Runtime access
- Packaging and distribution
- Tools
- Continuous Integration
ja builds on work by:
- The OpenJDK project
- The Maven project and Aether contributors
- Sonatype, which operates Maven Central and established its namespace conventions
- The JUnit team — support the development of JUnit
- The google-java-format project