GitHub

JBang Logo

Run any JAR or Java source file directly. JBang handles JDK downloads, dependency resolution, compilation, and caching so you can use the full Java ecosystem without the ceremony.

Release Downloads Build Status OpenSSF Scorecard Chat

What JBang does

At its simplest, JBang runs JARs and Java source files directly from the command line. Point it at a GAV coordinate, a URL, or a local .java file and it takes care of the rest: downloading a JDK if needed, resolving dependencies, compiling, caching, and running.

For single-file programs you declare dependencies with //DEPS comments instead of a build file. That is enough to pull anything from Maven Central (or your own repos) and have it on the classpath.

JBang also works with .jsh (JShell), .kt (Kotlin), .groovy, and .md (Markdown with embedded Java).

Examples

Run any JAR from Maven Central by its GAV coordinate:

jbang com.github.lalyos:jfiglet:0.0.9 "Hello JBang!"

A plain Java file with a naked main (Java 25+):

///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 25+
void main(String[] args) {
    System.out.println("Hello " + (args.length > 0 ? args[0] : "World"));
}

A CLI app with a dependency pulled from Maven Central:

///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS info.picocli:picocli:4.6.3
//JAVA 25+
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
@Command(name = "hello", mixinStandardHelpOptions = true)
class hello implements Runnable {
    @Parameters(index = "0", description = "The greeting to print")
    private String greeting;
    void main(String[] args) {
        new CommandLine(new hello()).execute(args);
    }
    public void run() {
        System.out.println("Hello " + greeting);
    }
}

A web server in a single file:

///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS io.javalin:javalin:7.1.0
//DEPS org.slf4j:slf4j-simple:2.0.17
//JAVA 25+
import io.javalin.Javalin;
void main() {
    Javalin.create(config -> {
        config.useVirtualThreads = true;
        config.router.mount(router -> {
            router.get("/", ctx -> ctx.result("Hello from JBang!"));
        });
    }).start(8000);
}

Read the original on github.com ↗