Java has paved the on-ramp for people learning Java and writing simple programs. ja lets those programs grow naturally into a module with dependencies, and later into multiple modules on a module source path, without requiring a complex build system.
ja uses the Java module descriptor as the source of truth throughout development. Start with one module in the current directory, add dependencies without changing the tools, and move the module beneath src when it enters source control or develops additional module boundaries.
- Declare dependencies directly in
module-info.java - Build, test, and distribute modules and applications from the same module declarations
- Preserve module boundaries and integrity from development through distribution
- Format source, find declarations and usages, browse APIs, and reuse compilation work across tools
- Keep output concise so coding agents can work effectively without losing important errors
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 creates a ja-enabled copy without modifying the source JDK.
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 | iexThe installer prints the steps needed to activate ja. See the installation guide for default locations, shell setup and completions, custom locations, and version pinning.
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